text: #!/usr/bin/env node
  var path = require('path'),
     fs = require('fs'),
     extend = require('util')._extend,
     exec = require('child_process').exec,
     processes = [];
  
  var baseDir = path.resolve(__dirname, '..'),
      srcDir = baseDir,
      chimpBin = path.resolve(baseDir, 'node_modules/.bin/chimp');
  
  var appOptions = {
    port: 3000,
    env: {
      ROOT_URL: 'http://localhost:3000/',
      VELOCITY: 1
    }
  };
  
  var mirrorOptions = {
    port: 3100,
    env: {
      IS_MIRROR: 1,
      MONGO_URL: 'mongodb://localhost:' + 3001 + '/chimp_db',
      ROOT_URL: 'http://localhost:3100/'
    },
    logFile: './chimp-mirror.log'
  };
  
  var chimpSwitches =
     ' --path=' + path.resolve('tests/features') +
     ' -r=' + path.resolve('tests/features/step_definitions');
  
  if (process.env.CI || process.env.TRAVIS || process.env.CIRCLECI) {
    // when not in Watch mode, Chimp existing will exit Meteor too
    // we also don't need Velocity for the app chimp will run against
    appOptions.env.VELOCITY = 0;
  } else {
    chimpSwitches += ' --watch';
  }
  
  if (process.env.SIMIAN_API && process.env.SIMIAN_REPOSITORY) {
    chimpSwitches += ' --simianRepositoryId=' + process.env.SIMIAN_REPOSITORY;
    chimpSwitches += ' --simianAccessToken=' + process.env.SIMIAN_API;
  }
  
  // set this flag to start with a mirror locally (ala Velocity xolvio:cucumber style)
  if (process.env.WITH_MIRROR) {
    chimpWithMirror();
  } else if (process.env.NO_METEOR) {
    startChimp('--ddp=' + appOptions.env.ROOT_URL + chimpSwitches);
  } else {
    chimpNoMirror();
  }
  
  // *************************************************
  
  function chimpWithMirror() {
    appOptions.waitForMessage = 'Started MongoDB';
    startApp(function () {
      startMirror(function () {
        console.log('=> Test App running at:', mirrorOptions.env.ROOT_URL);
        console.log('=> Log file: tail -f', path.resolve(mirrorOptions.logFile), '\n');
        startChimp('--ddp=' + mirrorOptions.env.ROOT_URL + chimpSwitches
        )
      });
    });
  }
  
  function chimpNoMirror() {
    appOptions.waitForMessage = 'App running at';
    startApp(function () {
      startChimp('--ddp=' + appOptions.env.ROOT_URL + chimpSwitches);
    });
  }
  
  function startApp(callback) {
    startProcess({
      name: 'Meteor App',
      command: 'meteor --port ' + appOptions.port,
      waitForMessage: appOptions.waitForMessage,
      options: {
        cwd: srcDir,
        env: extend(appOptions.env, process.env)
      }
    }, callback);
  }
  
  function startMirror(callback) {
    startProcess({
      name: 'Meteor Mirror',
      command: 'meteor --port ' + mirrorOptions.port,
      silent: true,
      logFile: mirrorOptions.logFile,
      waitForMessage: 'App running at',
      options: {
        cwd: srcDir,
        env: extend(mirrorOptions.env, process.env)
      }
    }, callback);
  }
  
  function startChimp(command) {
    startProcess({
      name: 'Chimp',
      command: chimpBin + ' ' + command
    });
  }
  
  function startProcess(opts, callback) {
    var proc = exec(
       opts.command,
       opts.options
    );
    if (opts.waitForMessage) {
      proc.stdout.on('data', function waitForMessage(data) {
        if (data.toString().match(opts.waitForMessage)) {
          if (callback) {
            callback();
          }
        }
      });
    }
    if (!opts.silent) {
      proc.stdout.pipe(process.stdout);
      proc.stderr.pipe(process.stderr);
    }
    if (opts.logFile) {
      var logStream = fs.createWriteStream(opts.logFile, {flags: 'a'});
      proc.stdout.pipe(logStream);
      proc.stderr.pipe(logStream);
    }
    proc.on('close', function (code) {
      console.log(opts.name, 'exited with code ' + code);
      for (var i = 0; i < processes.length; i += 1) {
        processes[i].kill();
      }
      process.exit(code);
    });
    processes.push(proc);
  }