lib/qx/tool/compiler/files/Utils.js
function(dir) {
      var drivePrefix = "";
      if (process.platform === "win32" && dir.match(/^[a-zA-Z]:/)) {
        drivePrefix = dir.substring(0, 2);
        dir = dir.substring(2);
      }
      dir = dir.replace(/\\/g, "/");
      var segs = dir.split("/");
      if (!segs.length) {
        return drivePrefix + dir;
      }  
      
      var currentDir;
      var index;
      if (segs[0].length) {
        currentDir = "";
        index = 0;
      } else {
        currentDir = "/";
        index = 1;
      }
      
      function bumpToNext(nextSeg) {
        index++;
        if (currentDir.length && currentDir !== "/") {
          currentDir += "/";
        }  
        currentDir += nextSeg;
        return next();
      }
      
      function next() {
        if (index == segs.length) {
          if (process.platform === "win32") {
            currentDir = currentDir.replace(/\//g, "\\"); 
          }
          return Promise.resolve(drivePrefix + currentDir);
        }
        
        let nextSeg = segs[index];
        if (nextSeg == "." || nextSeg == "..") {
          return bumpToNext(nextSeg);
        }
        
        return new Promise((resolve, reject) => {
          fs.readdir(currentDir.length == 0 ? "." : drivePrefix + currentDir, { encoding: "utf8" }, (err, files) => {
            if (err) {
              reject(err);
              return;
            }
            
            let nextLowerCase = nextSeg.toLowerCase();
            let exact = false;
            let insensitive = null;
            for (let i = 0; i < files.length; i++) {
              if (files[i] === nextSeg) {
                exact = true;
                break;
              }
              if (files[i].toLowerCase() === nextLowerCase) {
                insensitive = files[i];
              }
            }
            if (!exact && insensitive) {
              nextSeg = insensitive;
            }
            
            bumpToNext(nextSeg).then(resolve);
          });
        });
      }
      
      return new Promise((resolve, reject) => {
        fs.stat(drivePrefix + dir, err => {
          if (err) {
            if (err.code == "ENOENT") {
              resolve(drivePrefix + dir);
            } else {
              reject(err);
            }
          } else {
            next().then(resolve);
          }
        });
      });
    }
function(dir) {
      var drivePrefix = "";
      if (process.platform === "win32" && dir.match(/^[a-zA-Z]:/)) {
        drivePrefix = dir.substring(0, 2);
        dir = dir.substring(2);
      }
      dir = dir.replace(/\\/g, "/");
      var segs = dir.split("/");
      if (!segs.length) {
        return drivePrefix + dir;
      }  
      
      var currentDir;
      var index;
      if (segs[0].length) {
        currentDir = "";
        index = 0;
      } else {
        currentDir = "/";
        index = 1;
      }
      
      function bumpToNext(nextSeg) {
        index++;
        if (currentDir.length && currentDir !== "/") {
          currentDir += "/";
        }  
        currentDir += nextSeg;
        return next();
      }
      
      function next() {
        if (index == segs.length) {
          if (process.platform === "win32") {
            currentDir = currentDir.replace(/\//g, "\\"); 
          }
          return Promise.resolve(drivePrefix + currentDir);
        }
        
        let nextSeg = segs[index];
        if (nextSeg == "." || nextSeg == "..") {
          return bumpToNext(nextSeg);
        }
        
        return new Promise((resolve, reject) => {
          fs.readdir(currentDir.length == 0 ? "." : drivePrefix + currentDir, { encoding: "utf8" }, (err, files) => {
            if (err) {
              reject(err);
              return;
            }
            
            let nextLowerCase = nextSeg.toLowerCase();
            let exact = false;
            let insensitive = null;
            for (let i = 0; i < files.length; i++) {
              if (files[i] === nextSeg) {
                exact = true;
                break;
              }
              if (files[i].toLowerCase() === nextLowerCase) {
                insensitive = files[i];
              }
            }
            if (!exact && insensitive) {
              nextSeg = insensitive;
            }
            
            bumpToNext(nextSeg).then(resolve);
          });
        });
      }
      
      return new Promise((resolve, reject) => {
        fs.stat(drivePrefix + dir, err => {
          if (err) {
            if (err.code == "ENOENT") {
              resolve(drivePrefix + dir);
            } else {
              reject(err);
            }
          } else {
            next().then(resolve);
          }
        });
      });
    }
function ( dir ) { var drivePrefix = "" ; if ( process . platform === "win32" && dir . match ( / ^[a-zA-Z]: / ) ) { drivePrefix = dir . substring ( 0 , 2 ) ; dir = dir . substring ( 2 ) ; } dir = dir . replace ( / \\ / g , "/" ) ; var segs = dir . split ( "/" ) ; if ( ! segs . length ) { return drivePrefix + dir ; } var currentDir ; var index ; if ( segs [ 0 ] . length ) { currentDir = "" ; index = 0 ; } else { currentDir = "/" ; index = 1 ; } function bumpToNext ( nextSeg ) { index ++ ; if ( currentDir . length && currentDir !== "/" ) { currentDir += "/" ; } currentDir += nextSeg ; return next ( ) ; } function next ( ) { if ( index == segs . length ) { if ( process . platform === "win32" ) { currentDir = currentDir . replace ( / \/ / g , "\\" ) ; } return Promise . resolve ( drivePrefix + currentDir ) ; } let nextSeg = segs [ index ] ; if ( nextSeg == "." || nextSeg == ".." ) { return bumpToNext ( nextSeg ) ; } return new Promise ( ( resolve , reject ) => { fs . readdir ( currentDir . length == 0 ? "." : drivePrefix + currentDir , { encoding : "utf8" } , ( err , files ) => { if ( err ) { reject ( err ) ; return ; } let nextLowerCase = nextSeg . toLowerCase ( ) ; let exact = false ; let insensitive = null ; for ( let i = 0 ; i < files . length ; i ++ ) { if ( files [ i ] === nextSeg ) { exact = true ; break ; } if ( files [ i ] . toLowerCase ( ) === nextLowerCase ) { insensitive = files [ i ] ; } } if ( ! exact && insensitive ) { nextSeg = insensitive ; } bumpToNext ( nextSeg ) . then ( resolve ) ; } ) ; } ) ; } return new Promise ( ( resolve , reject ) => { fs . stat ( drivePrefix + dir , err => { if ( err ) { if ( err . code == "ENOENT" ) { resolve ( drivePrefix + dir ) ; } else { reject ( err ) ; } } else { next ( ) . then ( resolve ) ; } } ) ; } ) ; }
Normalises the path and corrects the case of the path to match what is actually on the filing system

@param fsPath {String} the filename to normalise
@returns {String} the new path
@async
Normalises the path and corrects the case of the path to match what is actually on the filing system