Processes the configuration from a JSON data structure and creates a Maker

@param data {Map}
@return {Maker}
async function(data) {
      var t = this;
      var maker = null;

      var outputPath = data.target.outputPath;
      if (!outputPath) {
        throw new qx.tool.cli.Utils.UserError("Missing output-path for target " + data.target.type);
      }

      maker = new qx.tool.compiler.makers.AppMaker();
      if (!this.argv["erase"]) {
        maker.setNoErase(true);
      }

      if (!data.target) {
        throw new qx.tool.cli.Utils.UserError("No target specified");
      }
      var targetClass = data.target.targetClass ? this.resolveTargetClass(data.target.targetClass): null;
      if (!targetClass && data.target.type) {
        targetClass = this.resolveTargetClass(data.target.type);
      }
      if (!targetClass) {
        throw new qx.tool.cli.Utils.UserError("Cannot find target class: " + (data.target.targetClass||data.target.type));
      }
      /* eslint-disable new-cap */
      var target = new targetClass(outputPath);
      /* eslint-enable new-cap */
      if (data.target.uri) {
        qx.tool.compiler.Console.print("qx.tool.cli.compile.deprecatedUri", "target.uri", data.target.uri);
      }
      if (data.target.writeCompileInfo) {
        target.setWriteCompileInfo(true);
      }
      target.setWriteLibraryInfo(this.argv.writeLibraryInfo);
      target.setUpdatePoFiles(this.argv.updatePoFiles);
      maker.setTarget(target);

      maker.setLocales(data.locales||[ "en" ]);
      if (data.writeAllTranslations) {
        maker.setWriteAllTranslations(data.writeAllTranslations);
      }

      if (typeof data.target.typescript == "string") {
        maker.set({ outputTypescript: true, outputTypescriptTo: data.target.typescript });
      } else if (typeof data.target.typescript == "boolean") {
        maker.set({ outputTypescript: true });
      }
      if (this.argv["typescript"]) {
        maker.set({ outputTypescript: true });
      }

      if (data.environment) {
        maker.setEnvironment(data.environment);
      }
      if (data.target.environment) {
        target.setEnvironment(data.target.environment);
      }

      if (data["path-mappings"]) {
        for (var from in data["path-mappings"]) {
          var to = data["path-mappings"][from];
          target.addPathMapping(from, to);
        }
      }

      function mergeArray(dest, ...srcs) {
        srcs.forEach(function(src) {
          if (src) {
            src.forEach(function(elem) {
              if (!qx.lang.Array.contains(dest, src)) {
                dest.push(elem);
              }
            });
          }
        });
        return dest;
      }
      let babelOptions = data.babelOptions || {};
      qx.lang.Object.mergeWith(babelOptions, data.target.babelOptions || {});
      maker.getAnalyser().setBabelOptions(babelOptions);

      var addCreatedAt = data.target["addCreatedAt"] || t.argv["addCreatedAt"];
      if (addCreatedAt) {
        maker.getAnalyser().setAddCreatedAt(true);
      }

      var appNames = null;
      if (t.argv["app-name"]) {
        appNames = t.argv["app-name"].split(",");
      }

      let hasExplicitDefaultApp = false;
      let defaultApp = null;
      data.applications.forEach(function(appData, appIndex) {
        if (appNames && appNames.indexOf(appData.name) === -1) {
          return;
        }
        var app = new qx.tool.compiler.app.Application(appData["class"]);
        [ "type", "theme", "name", "environment", "outputPath", "bootPath", "loaderTemplate"].forEach(name => {
          if (appData[name] !== undefined) {
            var fname = "set" + qx.lang.String.firstUp(name);
            app[fname](appData[name]);
          }
        });
        if (app.isBrowserApp()) {
          var setDefault;
          if (appData.writeIndexHtmlToRoot !== undefined) {
            qx.tool.compiler.Console.print("qx.tool.cli.compile.deprecatedCompileSeeOther", "application.writeIndexHtmlToRoot", "application.default");
            setDefault = appData.writeIndexHtmlToRoot;
          } else if (appData["default"] !== undefined) {
            setDefault = appData["default"];
          }

          if (setDefault !== undefined) {
            if (setDefault) {
              if (hasExplicitDefaultApp) {
                throw new qx.tool.cli.Utils.UserError("Error: Can only set one application to be the default application!");
              }
              hasExplicitDefaultApp = true;
              defaultApp = app;
            }
          } else if (!defaultApp) {
            defaultApp = app;
          }
        }
        if (appData.uri) {
          qx.tool.compiler.Console.print("qx.tool.cli.compile.deprecatedUri", "application.uri", appData.uri);
        }
        if (appData.title) {
          app.setTitle(appData.title);
        }

        // Take the command line for `minify` as most precedent only if provided
        var minify;
        if ((process.argv.indexOf("--minify") > -1)) {
          minify = t.argv["minify"];
        }
        minify = minify || appData["minify"] || data.target["minify"] || t.argv["minify"];
        if (typeof minify == "boolean") {
          minify = minify ? "minify" : "off";
        }
        if (!minify) {
          minify = "mangle";
        }
        if (typeof target.setMinify == "function") {
          target.setMinify(minify);
        }
        var saveUnminified = appData["save-unminified"] || data.target["save-unminified"] || t.argv["save-unminified"];
        if (typeof saveUnminified == "boolean" && typeof target.setSaveUnminified == "function") {
          target.setSaveUnminified(saveUnminified);
        }

        var parts = appData.parts || data.target.parts || data.parts;
        if (parts) {
          if (!parts.boot) {
            throw new qx.tool.cli.Utils.UserError("Cannot determine a boot part for application " + (appIndex + 1) + " " + (appData.name||""));
          }
          for (var partName in parts) {
            var partData = parts[partName];
            var include = typeof partData.include == "string" ? [ partData.include ] : partData.include;
            var exclude = typeof partData.exclude == "string" ? [ partData.exclude ] : partData.exclude;
            var part = new qx.tool.compiler.app.Part(partName, include, exclude).set({
              combine: Boolean(partData.combine),
              minify: Boolean(partData.minify)
            });
            app.addPart(part);
          }
        }

        if (target.getType() == "source" && t.argv.bundling) {
          var bundle = appData.bundle || data.target.bundle || data.bundle;
          if (bundle) {
            if (bundle.include) {
              app.setBundleInclude(bundle.include);
            }
            if (bundle.exclude) {
              app.setBundleExclude(bundle.exclude);
            }
          }
        }

        app.set({
          exclude: mergeArray([], data.exclude, data.target.exclude, appData.exclude),
          include: mergeArray([], data.include, data.target.include, appData.include)
        });
        maker.addApplication(app);
      });

      if (defaultApp) {
        defaultApp.setWriteIndexHtmlToRoot(true);
      } else {
        qx.tool.compiler.files.Utils.safeUnlink(target.getOutputDir() + target.getScriptPrefix() + "index.html");
      }

      maker.getAnalyser().addListener("compiledClass", function(evt) {
        var data = evt.getData();
        var markers = data.dbClassInfo.markers;
        if (markers) {
          markers.forEach(function(marker) {
            var str = qx.tool.compiler.Console.decodeMarker(marker);
            console.warn(data.classFile.getClassName() + ": " + str);
          });
        }
      });

      if (!data.libraries.every(libData => fs.existsSync(libData + "/Manifest.json"))) {
        console.log("One or more libraries not found - trying to install them from library repository...");
        const installer = new qx.tool.cli.commands.contrib.Install({
          quiet: true,
          save: false
        });
        await installer.process();
      }

      const addLibraryAsync = qx.tool.compiler.utils.Promisify.promisify(maker.addLibrary, maker);
      await qx.Promise.all(data.libraries.map(libData => addLibraryAsync(libData)));

      // Search for Qooxdoo library if not already provided
      var qxLib = maker.getAnalyser().findLibrary("qx");
      if (!qxLib) {
        await addLibraryAsync(await this.getGlobalQxPath());
      }
      if (this.argv.verbose) {
        qxLib = maker.getAnalyser().findLibrary("qx");
        console.log("QooxDoo found in " + qxLib.getRootDir());
      }
      return maker;
    }