docs: function bundler(options) {
          var allFiles = {};
          var bundles = {};
          var dir = options.src;
          var dest = options.dest;
          var resourcesFile = options.resourceJson;
          var indexBundles = options.indexBundles;
          var titleIndexBnudles = {};
          var traversed_bundles = {}, traversed_files = {}, excluded_bundles = {};
          var resourcesJs = {};
          for (var key in options) {
              resourcesJs[key] = options[key];
          }
          resourcesJs.bundles = bundles;
  
          function getFiles(packageName, files, bundledFile, includedBundles) {
              if (!traversed_bundles[packageName] && !excluded_bundles[packageName]) {
                  traversed_bundles[packageName] = true;
                  var bundle = resourcesJs.bundles[packageName];
                  if (bundle) {
                      bundle.bundled = bundle.bundled || [];
                      bundle.bundled_html = bundle.bundled_html || [];
                      bundle.in = bundle.in || [];
                      for (var i in bundle.on) {
                          files = getFiles(bundle.on[i], files, bundledFile, includedBundles);
                      }
                      for (var j in bundle.js) {
                          var _file2 = cleanURL(dir + "/" + bundle.js[j]);
                          if (!traversed_files[_file2]) {
                              files.js.push(_file2);
                              traversed_files[_file2] = packageName;
                          }
                      }
                      if (files.js.length > 0) {
                          bundle.bundled.push(bundledFile + ".js");
                      }
  
                      for (var i in bundle.html) {
                          var _file = cleanURL(dir + "/" + bundle.html[i]);
                          if (!traversed_files[_file]) {
                              files.html.push(_file);
                              traversed_files[_file] = packageName;
                          }
                      }
                      if (files.html.length > 0) {
                          bundle.bundled_html.push(bundledFile + ".html");
                      }
  
                      includedBundles.push(packageName);
                  }
              }
              return files;
          }
  
          if (TASK_BUNDLIFY || TASK_SCAN) {
              grunt.file.recurse(dir, function(abspath, rootdir, subdir, filename) {
                  if (filename === "module.json" && abspath.indexOf(dest) !== 0) {
                      var packageInfo = {};
                      if (grunt.file.exists(subdir + "/.bower.json")) {
                          var bowerJson = grunt.file.readJSON(subdir + "/.bower.json");
                          packageInfo.bowerName = bowerJson.name;
                          packageInfo.bowerVersion = bowerJson.version;
                      }
                      if (grunt.file.exists(subdir + "/composer.json")) {
                          var composerJson = grunt.file.readJSON(subdir + "/composer.json");
                          packageInfo.composerName = composerJson.name;
                          packageInfo.composerVersion = composerJson.version;
                      }
                      var _bundles = grunt.file.readJSON(abspath);
                      var packageName = _bundles.name;
                      if (_bundles.exclude) {
                          for (var i in _bundles.exclude) {
                              excluded_bundles[_bundles.exclude[i]] = true;
                          }
                      }
                      if (packageName !== undefined) {
                          titleIndexBnudles[packageName] = [];
                          for (var bundleName in _bundles) {
                              if ((bundleName === packageName || bundleName.indexOf(packageName + "/") === 0) && !excluded_bundles[bundleName]) {
                                  if (bundles[bundleName]) {
                                      console.log("====Duplicate Package", bundleName);
                                  } else if (!toIgnore(bundleName)) {
                                      titleIndexBnudles[packageName].push(bundleName);
                                  }
                                  bundles[bundleName] = { js: [], on: [], css: [], html: [], packageInfo: packageInfo};
                                  for (var file_i in _bundles[bundleName].js) {
                                      var js_file = subdir + "/" + _bundles[bundleName].js[file_i];
                                      bundles[bundleName].js.push(js_file);
                                      if (!allFiles[js_file]) {
                                          allFiles[js_file] = js_file;
                                      } else {
                                          console.log("====Duplicate File" + js_file);
                                      }
                                  }
                                  for (var file_j in _bundles[bundleName].css) {
                                      var css_file = subdir + "/" + _bundles[bundleName].css[file_j];
                                      bundles[bundleName].css.push(css_file);
                                      if (!allFiles[css_file]) {
                                          allFiles[css_file] = css_file;
                                      } else {
                                          console.log("====Duplicate File" + css_file);
                                      }
                                  }
                                  for (var file_k in _bundles[bundleName].html) {
                                      var html_file = subdir + "/" + _bundles[bundleName].html[file_k];
                                      bundles[bundleName].html.push(html_file);
                                      if (!allFiles[html_file]) {
                                          allFiles[html_file] = html_file;
                                      } else {
                                          console.log("====Duplicate File" + html_file);
                                      }
                                  }
                                  bundles[bundleName].on = _bundles[bundleName].on || [];
                                  console.log("╬═╬ Module.json", abspath);
                                  //console.log(bundleName, _bundles[bundleName].on);
                              }
                          }
                      }
                  }
              });
  
  
              var titleIndexBnudlesNames = Object.keys(titleIndexBnudles);
  
              if (options.modulize) {
                  titleIndexBnudlesNames.map(function(bundName) {
                      if (!bundles[bundName] && !toIgnore(bundName)) {
                          bundles[bundName] = { js: [], on: titleIndexBnudles[bundName], css: [], html: [], packageInfo: {}};
                          console.log("New Package ", bundName, bundles[bundName]);
                      }
                  });
              }
  
              for (var packageKey in excluded_bundles) {
                  delete bundles[packageKey];
              }
  
              var firstIndexBundled = null;
  
              if (!TASK_SKIP_INIT) {
                  var myIndexBnudles = indexBundles;
                  if (TASK_BUNDLIFY) {
  
                      var moreBundles = Object.keys(bundles);
  
                      if (options.sort) {
                          moreBundles = moreBundles.sort();
                      }
  
                      if (options.projectPrefix !== undefined) {
                          myIndexBnudles = uniqueArray(myIndexBnudles.concat(titleIndexBnudlesNames.concat(moreBundles).filter(function(bundleName) {
                              return bundleName.indexOf(options.projectPrefix) === 0;
                          })));
                      }
  
                      myIndexBnudles = uniqueArray(myIndexBnudles.concat(titleIndexBnudlesNames.concat(moreBundles))).filter(function(bundleName) {
                          return !toIgnore(bundleName);
                      });
  
                  }
                  console.log("Bundles in Order", myIndexBnudles);
  
                  var prevBundle = null;
                  myIndexBnudles.forEach(function(bundleName) {
                      var _bundleMap = {};
                      var includedBundles = [];
                      var bundledFile = dest + "/bootloader_bundled/" + bundleName.split("/").join(".");
                      var bundledFile_js = bundledFile + ".js";
                      var files = getFiles(bundleName, {js: [], html: []}, bundledFile, includedBundles);
                      var js_files = uniqueArray(files.js.reverse()).reverse();
                      if (js_files.length > 0) {
                          if (!firstIndexBundled && options.resourcesInline) {
                              firstIndexBundled = bundleName;
                              js_files.unshift(resourcesFile + ".js");
                          }
                          _bundleMap[bundledFile_js] = js_files;
                          //console.log("files",bundleName,files.length,files);
                          setBundleConfig(bundleName, _bundleMap, includedBundles, bundledFile_js);
  
                          if (prevBundle && options.order) {
                              var bundle = resourcesJs.bundles[bundleName];
                              if (bundle) {
                                  bundle.on = [prevBundle].concat(bundle.on);
                              }
                          }
                          prevBundle = bundleName;
  
                      } else console.log("╬═╬ No File in bundle to bundlify thus skipping ", bundleName);
  
                      var html_files = uniqueArray(files.html.reverse()).reverse();
                      if (html_files.length) {
                          var html_file_content = "";
                          for (var i in html_files) {
                              html_file_content += '<script type="text/html" src="' + html_files[i] + '">' + grunt.file.read(html_files[i]).split("\t").join("")
                                  .split("\n").join(" ")
                                  .split(">").map(function(v) {
                                      return v.trim();
                                  }).join(">") + '</script>';
                          }
                          grunt.file.write(bundledFile + ".html", html_file_content);
                      }
  
                  });
  
                  resourcesJs.gitinfo = grunt.config().gitinfo;
                  if (firstIndexBundled) {
                      var resJsonString = JSON.stringify({
                          RESOURCES_JSON: resourcesJs,
                          RESOURCES_FILE: resourcesFile
                      }).replace(/\r?\n|\r|\\n/g, ' ');
  
                      var packed = resJsonString;
                      var unpack = "";
                      if(options.jsonpack){
                          var jsonpack = require('jsonpack/main');
                          var fs = require("fs");
                          unpack = grunt.file.read('node_modules/jsonpack/main.js');
                          packed =('(jsonpack.unpack(\''+jsonpack.pack(resJsonString)+'\'))');
                      }
  
                      grunt.file.write(resourcesFile + ".js", unpack+";var _BOOTLOADER_CONFIG_=" + packed);
                      resourcesJs.bundles[firstIndexBundled].js.unshift(resourcesFile + ".js");
                  }
  
                  grunt.task.run("uglify");
              }
  
              grunt.file.write(resourcesFile, JSON.stringify(resourcesJs));
  
          }
      }