whole_func_string: function(from, to, filter) {
        var t = this;
  
        function copy(statFrom, statTo) {
          if (statFrom.isDirectory()) {
            var p;
            if (statTo === null) {
              p = mkdir(to); 
            } else {
              p = Promise.resolve(); 
            }
            return p.then(() => readdir(from)
                .then(files => Promise.all(files.map(file => t.sync(from + "/" + file, to + "/" + file, filter)))));
            
          } else if (statFrom.isFile()) {
            return qx.Promise.resolve(filter ? filter(from, to) : true)
              .then(result => result && t.copyFile(from, to));
          }
          return undefined;
        }
  
        return new Promise((resolve, reject) => {
          var statFrom = null;
          var statTo = null;
          
          stat(from)
            .then(tmp => {
              statFrom = tmp;
              return stat(to)
                .then(tmp => statTo = tmp)
                .catch(err => {
                  if (err.code !== "ENOENT") {
                    throw err;
                  }
                });
            })
            .then(() => {
              if (!statTo || statFrom.isDirectory() != statTo.isDirectory()) {
                return t.deleteRecursive(to)
                  .then(() => copy(statFrom, statTo));
              } else if (statFrom.isDirectory() || (statFrom.mtime.getTime() > statTo.mtime.getTime() || statFrom.size != statTo.size)) {
                return copy(statFrom, statTo);
              }
              return undefined;
            })
            .then(resolve)
            .catch(reject);
        });
      }
func_code_string: function(from, to, filter) {
        var t = this;
  
        function copy(statFrom, statTo) {
          if (statFrom.isDirectory()) {
            var p;
            if (statTo === null) {
              p = mkdir(to); 
            } else {
              p = Promise.resolve(); 
            }
            return p.then(() => readdir(from)
                .then(files => Promise.all(files.map(file => t.sync(from + "/" + file, to + "/" + file, filter)))));
            
          } else if (statFrom.isFile()) {
            return qx.Promise.resolve(filter ? filter(from, to) : true)
              .then(result => result && t.copyFile(from, to));
          }
          return undefined;
        }
  
        return new Promise((resolve, reject) => {
          var statFrom = null;
          var statTo = null;
          
          stat(from)
            .then(tmp => {
              statFrom = tmp;
              return stat(to)
                .then(tmp => statTo = tmp)
                .catch(err => {
                  if (err.code !== "ENOENT") {
                    throw err;
                  }
                });
            })
            .then(() => {
              if (!statTo || statFrom.isDirectory() != statTo.isDirectory()) {
                return t.deleteRecursive(to)
                  .then(() => copy(statFrom, statTo));
              } else if (statFrom.isDirectory() || (statFrom.mtime.getTime() > statTo.mtime.getTime() || statFrom.size != statTo.size)) {
                return copy(statFrom, statTo);
              }
              return undefined;
            })
            .then(resolve)
            .catch(reject);
        });
      }
func_documentation_string: Synchronises two files or folders; files are copied from/to but only if their
  modification time or size has changed.
  @param from {String} path to copy from
  @param to {String} path to copy to
  @param filter {Function?} optional filter method to validate filenames before sync
  @async