whole_func_string: function() {
        var t = this;
        var Console = qx.tool.compiler.Console.getInstance();
        var analyser = this.getAnalyser();
        var db = analyser.getDatabase();
        var allDeps = new qx.tool.compiler.utils.IndexedArray();
        var exclude = {};
        var fatalCompileErrors = [];
  
        this.__loadDeps = null;
        
        var partsByName = {};
        var parts = [];
        var bootPart = null;
        var classDataByClassname = {};
        
        if (this.__parts && this.__parts.length) {
          parts = [];
          t.__parts.forEach(part => {
            if (partsByName[part.getName()]) {
              throw new Error(Console.decode("qx.tool.compiler.application.duplicatePartNames", part.getName())); 
            }
            var partData = {
                name: part.getName(),
                include: part.getInclude(),
                exclude: part.getExclude(),
                classes: [],
                dependsOn: {},
                combine: part.getCombine(),
                minify: part.getMinify()
            };
            partData.match = qx.tool.compiler.app.Application.createWildcardMatchFunction(part.getInclude(), part.getExclude());
            partsByName[part.getName()] = partData;
            parts.push(partData);
          });
          bootPart = partsByName.boot;
          if (!bootPart) {
            throw new Error(Console.decode("qx.tool.compiler.application.noBootPart")); 
          } 
        } else {
          bootPart = {
              name: "boot",
              include:[ "*" ],
              exclude: [],
              classes: [],
              dependsOn: {},
              combine: false,
              minify: false,
              match: function() {
                return true; 
              }
          };
          partsByName.boot = bootPart;
          parts.push(bootPart);
        }
        
        function createClassData(classname) {
          if (classDataByClassname[classname]) {
            return classDataByClassname[classname];
          }
          var classData = classDataByClassname[classname] = {
              classname: classname,
              parts: {},
              best: null,
              actual: null
          };
          parts.forEach(part => {
            if (part === bootPart) {
              return;
            }
            var result = part.match(classname);
            if (result !== null) {
              classData.parts[part.name] = result;
            
              var lastMatch = classData.best && classData.parts[classData.best.name];
              if (lastMatch === undefined || lastMatch === null) {
                classData.best = part; 
              
              // Exact
              } else if (lastMatch === "exact") {
                if (result === "exact") {
                  Console.print("qx.tool.compiler.application.conflictingExactPart", classname, part.name, classData.best.name); 
                }
              
              // Wildcard
              } else {
                qx.core.Assert.assertTrue(typeof lastMatch == "number");
                if (result === "exact") {
                  classData.best = part;
                  classData.exact = true;
                } else {
                  qx.core.Assert.assertTrue(typeof result == "number");
                  if (lastMatch === result) {
                    Console.print("qx.tool.compiler.application.conflictingBestPart", classname, part.name, classData.best.name); 
                  } else if (lastMatch < result) {
                    classData.best = part;
                  }
                }
              }
            }
          });
          return classData;
        }
        
        var needed = new qx.tool.compiler.utils.IndexedArray();
        var neededIndex = 0;
        var stack = new qx.tool.compiler.utils.IndexedArray();
        
        
        /*
         * We could say that when a class is `.require`d, then we treat any of it's `construct:true` dependencies as `require:true`
         * The problem is given this example:
         *    qx.core.Init.defer()
         *      qx.event.Registration.addListener
         *        qx.event.Registration.getManager
         *          qx.event.Manager.construct
         *            new qx.util.DeferredCall
         *            
         *    new qx.util.DeferredCall is a runtime only dependency so is not available.
         *    
         * So the theory is that deferred calls tend to be about initialisation, so prioritising constructor dependencies
         * may be helpful
         */
        
        /*
         * Recursively finds all the dependencies for a class which have not already been added
         * to the list of classes to load.
         * 
         *  @param classname {String}
         *  @param deps {String[]} array to modify
         */
        function compileAllRemainingDeps(classname, deps) {
          var checked = {};
          var depNames = { };
          depNames[classname] = true;
          
          function search(classname) {
            if (checked[classname]) {
              return;
            }
            checked[classname] = true;
  
            var info = db.classInfo[classname];
            if (info && info.dependsOn) {
              for (var depName in info.dependsOn) {
                var dd = info.dependsOn[depName];
                if (dd.load || dd.require || dd.defer || dd.construct) {
                  if (!allDeps.contains(depName)) {
                    depNames[depName] = true; 
                  }
                  search(depName);
                }
              }
            }
          }
          
          search(classname);
          for (var depName in depNames) {
            deps.push(depName);
          }
        }
  
        var addDepDepth = 0;
        function addDep(classname) {
          if (exclude[classname]) {
            return;
          }
          if (allDeps.contains(classname) || stack.contains(classname)) {
            return;
          }
  
          var info = db.classInfo[classname];
          if (!info) {
            return;
          }
          if (info.fatalCompileError) {
            fatalCompileErrors.push(classname);
          }
          
          addDepDepth++;
          
          var environmentLoadDeps = {};
          if (info.environment && info.environment.required) {
            for (var key in info.environment.required) {
              var envInfo = info.environment.required[key];
              if (envInfo.defer) {
                environmentLoadDeps[envInfo.className] = true; 
              }
            }
          }
          
          var deferDeps = [];
          if (info.dependsOn) {
            stack.push(classname);
            for (var depName in info.dependsOn) {
              var dd = info.dependsOn[depName];
              if (dd.load || dd.require || environmentLoadDeps[depName]) {
                addDep(depName);
              } else if (dd.defer) {
                deferDeps.push(depName);
              } else if (!allDeps.contains(depName)) {
                needed.push(depName); 
              }
            }
            stack.remove(classname);
          }
  
          if (parts && !allDeps.contains(classname)) {
            var classData = createClassData(classname);
            var part = classData.best||bootPart;
            part.classes.push(classname);
            classData.actual = part;
          }
          allDeps.push(classname);
          deferDeps.forEach(function(depName) {
            var deps = [];
            compileAllRemainingDeps(depName, deps);
            deps.forEach(addDep);
          });
          if (addDepDepth === 1) {
            while (neededIndex < needed.getLength()) {
              classname = needed.getItem(neededIndex++);
              addDep(classname);
            }
          }
          addDepDepth--;
        }
  
        exclude = {};
        t.__expandClassnames(t.getExclude()).forEach(name => exclude[name] = true);
        
        // Start the ball rolling
        addDep("qx.core.Object");
        t.getRequiredClasses().forEach(function(classname) {
          addDep(classname);
        });
        if (t.getTheme()) {
          addDep(t.getTheme());
        }
        /*
        parts.forEach((part) => {
          if (part !== bootPart) {
            t.__expandClassnames(part.include).forEach((name) => addDep(name));
          }
        });
        */
        
        while (neededIndex < needed.length) {
          var classname = needed[neededIndex++];
          addDep(classname);
        }
        
        if (parts && parts.length > 1) {
          // Calculate inter-part dependencies
          parts.forEach(part => {
            var checked = {};
            function check(classname) {
              if (checked[classname]) {
                return; 
              }
              checked[classname] = true;
              var classData = classDataByClassname[classname];
              if (classData.actual !== part) {
                part.dependsOn[classData.actual.name] = true;
              }
              for (var depName in db.classInfo.dependsOn) {
                check(depName); 
              }
            }
            part.classes.forEach(check);
            part.dependsOn = Object.keys(part.dependsOn);
          });
          
          // Check for recursive dependencies 
          parts.forEach(part => {
            var checked = {};
            function check(partname) {
              if (checked[partname]) {
                return false;
              }
              checked[partname] = true;
              var checkPart = partsByName[partname];
              if (checkPart === part) {
                return true; 
              }
              return part.dependsOn.some(check);
            }
            if (part.dependsOn.some(check)) {
              Console.print("qx.tool.compiler.application.partRecursive", part.name); 
            }
          });
        }
        
        /*
         * Done
         */
  
        this.__loadDeps = allDeps.toArray();
        
        var requiredLibs = {};
        this.__loadDeps.forEach(classname => {
          let classInfo = db.classInfo[classname];
          if (classInfo.assets) {
            classInfo.assets.forEach(asset => {
              var pos = asset.indexOf('/');
              if (pos > -1) {
                var ns = asset.substring(0, pos);
                if (analyser.findLibrary(ns))
                  requiredLibs[ns] = true;
              }
            });
          }
          requiredLibs[classInfo.libraryName] = true;
        });
        this.__requiredLibs = [];
        for (let ns in requiredLibs) {
          if (analyser.findLibrary(ns)) {
            this.__requiredLibs.push(ns);
          } else {
            Console.print("qx.tool.compiler.application.missingRequiredLibrary", ns);
          }
        }
        
        this.__partsDeps = parts;
        this.__fatalCompileErrors = fatalCompileErrors.length ? fatalCompileErrors : null;
      }
func_code_string: function() {
        var t = this;
        var Console = qx.tool.compiler.Console.getInstance();
        var analyser = this.getAnalyser();
        var db = analyser.getDatabase();
        var allDeps = new qx.tool.compiler.utils.IndexedArray();
        var exclude = {};
        var fatalCompileErrors = [];
  
        this.__loadDeps = null;
        
        var partsByName = {};
        var parts = [];
        var bootPart = null;
        var classDataByClassname = {};
        
        if (this.__parts && this.__parts.length) {
          parts = [];
          t.__parts.forEach(part => {
            if (partsByName[part.getName()]) {
              throw new Error(Console.decode("qx.tool.compiler.application.duplicatePartNames", part.getName())); 
            }
            var partData = {
                name: part.getName(),
                include: part.getInclude(),
                exclude: part.getExclude(),
                classes: [],
                dependsOn: {},
                combine: part.getCombine(),
                minify: part.getMinify()
            };
            partData.match = qx.tool.compiler.app.Application.createWildcardMatchFunction(part.getInclude(), part.getExclude());
            partsByName[part.getName()] = partData;
            parts.push(partData);
          });
          bootPart = partsByName.boot;
          if (!bootPart) {
            throw new Error(Console.decode("qx.tool.compiler.application.noBootPart")); 
          } 
        } else {
          bootPart = {
              name: "boot",
              include:[ "*" ],
              exclude: [],
              classes: [],
              dependsOn: {},
              combine: false,
              minify: false,
              match: function() {
                return true; 
              }
          };
          partsByName.boot = bootPart;
          parts.push(bootPart);
        }
        
        function createClassData(classname) {
          if (classDataByClassname[classname]) {
            return classDataByClassname[classname];
          }
          var classData = classDataByClassname[classname] = {
              classname: classname,
              parts: {},
              best: null,
              actual: null
          };
          parts.forEach(part => {
            if (part === bootPart) {
              return;
            }
            var result = part.match(classname);
            if (result !== null) {
              classData.parts[part.name] = result;
            
              var lastMatch = classData.best && classData.parts[classData.best.name];
              if (lastMatch === undefined || lastMatch === null) {
                classData.best = part; 
              
              // Exact
              } else if (lastMatch === "exact") {
                if (result === "exact") {
                  Console.print("qx.tool.compiler.application.conflictingExactPart", classname, part.name, classData.best.name); 
                }
              
              // Wildcard
              } else {
                qx.core.Assert.assertTrue(typeof lastMatch == "number");
                if (result === "exact") {
                  classData.best = part;
                  classData.exact = true;
                } else {
                  qx.core.Assert.assertTrue(typeof result == "number");
                  if (lastMatch === result) {
                    Console.print("qx.tool.compiler.application.conflictingBestPart", classname, part.name, classData.best.name); 
                  } else if (lastMatch < result) {
                    classData.best = part;
                  }
                }
              }
            }
          });
          return classData;
        }
        
        var needed = new qx.tool.compiler.utils.IndexedArray();
        var neededIndex = 0;
        var stack = new qx.tool.compiler.utils.IndexedArray();
        
        
        /*
         * We could say that when a class is `.require`d, then we treat any of it's `construct:true` dependencies as `require:true`
         * The problem is given this example:
         *    qx.core.Init.defer()
         *      qx.event.Registration.addListener
         *        qx.event.Registration.getManager
         *          qx.event.Manager.construct
         *            new qx.util.DeferredCall
         *            
         *    new qx.util.DeferredCall is a runtime only dependency so is not available.
         *    
         * So the theory is that deferred calls tend to be about initialisation, so prioritising constructor dependencies
         * may be helpful
         */
        
        /*
         * Recursively finds all the dependencies for a class which have not already been added
         * to the list of classes to load.
         * 
         *  @param classname {String}
         *  @param deps {String[]} array to modify
         */
        function compileAllRemainingDeps(classname, deps) {
          var checked = {};
          var depNames = { };
          depNames[classname] = true;
          
          function search(classname) {
            if (checked[classname]) {
              return;
            }
            checked[classname] = true;
  
            var info = db.classInfo[classname];
            if (info && info.dependsOn) {
              for (var depName in info.dependsOn) {
                var dd = info.dependsOn[depName];
                if (dd.load || dd.require || dd.defer || dd.construct) {
                  if (!allDeps.contains(depName)) {
                    depNames[depName] = true; 
                  }
                  search(depName);
                }
              }
            }
          }
          
          search(classname);
          for (var depName in depNames) {
            deps.push(depName);
          }
        }
  
        var addDepDepth = 0;
        function addDep(classname) {
          if (exclude[classname]) {
            return;
          }
          if (allDeps.contains(classname) || stack.contains(classname)) {
            return;
          }
  
          var info = db.classInfo[classname];
          if (!info) {
            return;
          }
          if (info.fatalCompileError) {
            fatalCompileErrors.push(classname);
          }
          
          addDepDepth++;
          
          var environmentLoadDeps = {};
          if (info.environment && info.environment.required) {
            for (var key in info.environment.required) {
              var envInfo = info.environment.required[key];
              if (envInfo.defer) {
                environmentLoadDeps[envInfo.className] = true; 
              }
            }
          }
          
          var deferDeps = [];
          if (info.dependsOn) {
            stack.push(classname);
            for (var depName in info.dependsOn) {
              var dd = info.dependsOn[depName];
              if (dd.load || dd.require || environmentLoadDeps[depName]) {
                addDep(depName);
              } else if (dd.defer) {
                deferDeps.push(depName);
              } else if (!allDeps.contains(depName)) {
                needed.push(depName); 
              }
            }
            stack.remove(classname);
          }
  
          if (parts && !allDeps.contains(classname)) {
            var classData = createClassData(classname);
            var part = classData.best||bootPart;
            part.classes.push(classname);
            classData.actual = part;
          }
          allDeps.push(classname);
          deferDeps.forEach(function(depName) {
            var deps = [];
            compileAllRemainingDeps(depName, deps);
            deps.forEach(addDep);
          });
          if (addDepDepth === 1) {
            while (neededIndex < needed.getLength()) {
              classname = needed.getItem(neededIndex++);
              addDep(classname);
            }
          }
          addDepDepth--;
        }
  
        exclude = {};
        t.__expandClassnames(t.getExclude()).forEach(name => exclude[name] = true);
        
        // Start the ball rolling
        addDep("qx.core.Object");
        t.getRequiredClasses().forEach(function(classname) {
          addDep(classname);
        });
        if (t.getTheme()) {
          addDep(t.getTheme());
        }
        /*
        parts.forEach((part) => {
          if (part !== bootPart) {
            t.__expandClassnames(part.include).forEach((name) => addDep(name));
          }
        });
        */
        
        while (neededIndex < needed.length) {
          var classname = needed[neededIndex++];
          addDep(classname);
        }
        
        if (parts && parts.length > 1) {
          // Calculate inter-part dependencies
          parts.forEach(part => {
            var checked = {};
            function check(classname) {
              if (checked[classname]) {
                return; 
              }
              checked[classname] = true;
              var classData = classDataByClassname[classname];
              if (classData.actual !== part) {
                part.dependsOn[classData.actual.name] = true;
              }
              for (var depName in db.classInfo.dependsOn) {
                check(depName); 
              }
            }
            part.classes.forEach(check);
            part.dependsOn = Object.keys(part.dependsOn);
          });
          
          // Check for recursive dependencies 
          parts.forEach(part => {
            var checked = {};
            function check(partname) {
              if (checked[partname]) {
                return false;
              }
              checked[partname] = true;
              var checkPart = partsByName[partname];
              if (checkPart === part) {
                return true; 
              }
              return part.dependsOn.some(check);
            }
            if (part.dependsOn.some(check)) {
              Console.print("qx.tool.compiler.application.partRecursive", part.name); 
            }
          });
        }
        
        /*
         * Done
         */
  
        this.__loadDeps = allDeps.toArray();
        
        var requiredLibs = {};
        this.__loadDeps.forEach(classname => {
          let classInfo = db.classInfo[classname];
          if (classInfo.assets) {
            classInfo.assets.forEach(asset => {
              var pos = asset.indexOf('/');
              if (pos > -1) {
                var ns = asset.substring(0, pos);
                if (analyser.findLibrary(ns))
                  requiredLibs[ns] = true;
              }
            });
          }
          requiredLibs[classInfo.libraryName] = true;
        });
        this.__requiredLibs = [];
        for (let ns in requiredLibs) {
          if (analyser.findLibrary(ns)) {
            this.__requiredLibs.push(ns);
          } else {
            Console.print("qx.tool.compiler.application.missingRequiredLibrary", ns);
          }
        }
        
        this.__partsDeps = parts;
        this.__fatalCompileErrors = fatalCompileErrors.length ? fatalCompileErrors : null;
      }
func_documentation_string: Calculates the dependencies of the classes to create a load order
  
  @param classes