Compiles the files in "filenames" along with any associated modules, into a
single js file, in proper module dependency order.

@param {Array.<string>} filenames The list of files to compile and concat.
@param {Object} options A container for misc options. 'depTarget' is the
only currently available option, which results in the dependencies for
'filenames' being printed to stdout, with 'depTarget' as the target.
@param {ErrorReporter} reporter
@param {Function} callback Callback used to return the result. A null result
indicates that inlineAndCompile has returned successfully from a
non-compile request.
@param {Function} errback Callback used to return errors.
function inlineAndCompile(filenames, options, reporter, callback, errback) {

  var depTarget = options && options.depTarget;
  var referrerName = options && options.referrer;

  var basePath;
  if (referrerName) {
    // The compile occurs two directories down from current directory,
    // in src/node.  Thus the names will appear as eg ../src/x.
    // We want something like referrerName/src/x. So we need to give
    // the normalize() the 'package' or root name with src/node append
    // to represent the referrer from here.
    referrerName = referrerName && referrerName + 'src/node';
    // The basePath will replace options.referrer in our final filename.
    // Since we are in src/node, we need to back up two directories.
    basePath = path.join(__dirname, '../../');
  } else {
    basePath = path.resolve('./') + '/';
  }
  basePath = basePath.replace(/\\/g, '/');

  var scriptsCount = options.scripts.length;

  var loadCount = 0;
  var elements = [];
  var hooks = new InlineLoaderHooks(reporter, basePath, elements, depTarget);
  var loader = new TraceurLoader(hooks);

  function appendEvaluateModule(name, referrerName) {
    var normalizedName =
        traceur.ModuleStore.normalize(name, referrerName);
    // Create tree for System.get('normalizedName');
    var tree =
        traceur.codegeneration.module.createModuleEvaluationStatement(normalizedName);
    elements.push(tree);
  }

  function loadNext() {
    var loadAsScript = scriptsCount && (loadCount < scriptsCount);
    var doEvaluateModule = false;
    var loadFunction = loader.import;
    var name = filenames[loadCount];
    if (loadAsScript) {
      loadFunction = loader.loadAsScript;
    } else {
      name = name.replace(/\.js$/,'');
      if (options.modules !== 'inline' && options.modules !== 'instantiate')
        doEvaluateModule = true;
    }
    var loadOptions = {referrerName: referrerName};
    var codeUnit = loadFunction.call(loader, name, loadOptions).then(
        function() {
          if (doEvaluateModule)
            appendEvaluateModule(name, referrerName);
          loadCount++;
          if (loadCount < filenames.length) {
            loadNext();
          } else if (depTarget) {
            callback(null);
          } else {
            var tree = allLoaded(basePath, reporter, elements);
            callback(tree);
          }
        }, function(err) {
          errback(err);
        }).catch(function(ex) {
          console.error('Internal error ' + (ex.stack || ex));
        });
  }

  loadNext();
}