docs: function ChildProcessFactory (
      nodeChildProcess,
      Errors,
      Logger,
      assert,
      util,
      Promise,
      Constants,
      _,
      fs,
      path
  ) {
      var logger = Logger.initialize(ChildProcessFactory);
  
      /**
       * ChildProcess provides a promise based mechanism to run shell commands
       * in a fairly secure manner.
       * @constructor
       */
      function ChildProcess (command, args, env, code, maxBuffer) {
          var self = this;
  
          assert.string(command);
          assert.optionalArrayOfNumber(code);
  
          self.command = command;
          self.file = self._parseCommandPath(self.command);
          self.args = args;
          self.environment = env || {};
          self.exitCode = code || [0];
          self.maxBuffer = maxBuffer || Constants.ChildProcess.MaxBuffer;
  
          if (!self.file) {
              throw new Error('Unable to locate command file (' + self.command +').');
          }
          if (!_.isEmpty(self.args)) {
              try {
                  assert.arrayOfString(self.args, 'ChildProcess command arguments');
              } catch (e) {
                  throw new Error('args must be an array of strings');
              }
          }
  
          self.hasBeenKilled = false;
          self.hasBeenCancelled = false;
          self.spawnInstance = undefined;
      }
  
      ChildProcess.prototype.createOwnDeferred = function() {
          var self = this;
          self._deferred = new Promise(function(resolve, reject) {
              self._resolve = resolve;
              self._reject = reject;
          });
      };
  
      ChildProcess.prototype.resolve = function(result) {
          if (!this._deferred.isPending()) {
              logger.error("ChildProcess promise has already been resolved");
              return;
          } else {
              this._resolve(result);
          }
      };
  
      ChildProcess.prototype.reject = function(error) {
          if (!this._deferred.isPending()) {
              logger.error("ChildProcess promise has already been rejected");
              return;
          } else {
              this._reject(error);
          }
      };
  
      ChildProcess.prototype.killSafe = function (signal) {
          if (!this.hasBeenKilled && this.spawnInstance && _.isFunction(this.spawnInstance.kill)) {
              this.spawnInstance.kill(signal);
          }
          this.hasBeenCancelled = true;
      };
  
      /**
       * Runs the given command.
       * @param  {String} command File to run, with path or without.
       * @param  {String[]} args    Arguments to the file.
       * @param  {Object} env     Optional environment variables to provide.
       * @param  {Integer} code   Desired exit code, defaults to 0.
       * @return {Promise}        A promise fulfilled with the stdout, stderr of
       * a successful command.
       */
      ChildProcess.prototype._run = function () {
          var self = this;
  
          if (self.hasBeenCancelled) {
              self.reject(new Errors.JobKilledError("ChildProcess job has been cancelled", {
                  command: self.command,
                  argv: self.args
              }));
              return;
          }
  
          self.hasBeenKilled = false;
  
          var options = {
              env: self.environment,
              maxBuffer: self.maxBuffer
          };
  
          self.spawnInstance = nodeChildProcess.execFile(
                  self.file, self.args, options, function (error, stdout, stderr) {
  
              if (error && self.exitCode.indexOf(error.code) === -1) {
                  self.hasBeenKilled = true;
                  logger.error('Error Running ChildProcess.', {
                      file: self.file,
                      argv: self.args,
                      stdout: stdout,
                      stderr: stderr,
                      error: error
                  });
                  self.reject(error);
              } else {
                  self.hasBeenKilled = true;
                  self.resolve({
                      stdout: stdout,
                      stderr: stderr
                  });
              }
          })
          .on('close', function(code, signal) {
              if (signal) {
                  logger.warning("Child process received closing signal:", {
                      signal: signal,
                      argv: self.args
                  });
              }
              self.hasBeenKilled = true;
          })
          .on('error', function(code, signal) {
              logger.error("Child process received closing signal but has " +
                  "already been closed!!!", {
                  signal: signal,
                  argv: self.args
              });
          });
      };
  
      ChildProcess.prototype._runWithRetries = function(retryCount, delay, retries) {
          var self = this;
  
          // Max out exponential backoff to 60 seconds.
          delay = delay > 60000 ? 60000 : delay;
  
          if (!self._deferred) {
              self.createOwnDeferred();
          }
  
          self._run();
  
          return self._deferred.catch(function(e) {
              if (e instanceof Errors.JobKilledError) {
                  throw e;
              } else if (retryCount < retries) {
                  logger.debug("Retrying ChildProcess command.", {
                      file: self.file,
                      args: self.args
                  });
                  // Create new deferred promise in here instead of above, in case we receive an
                  // external cancellation during the below delay, so we don't
                  // try to reject using the previous deferred object.
                  self.createOwnDeferred();
                  return Promise.delay(delay)
                  .then(function() {
                      return self._runWithRetries(retryCount + 1, delay * 2, retries);
                  });
              } else {
                  throw e;
              }
          });
      };
  
      ChildProcess.prototype.run = function(options) {
          options = options || {};
          options.retries = options.retries || 0;
          if (options.delay !== 0) {
              options.delay = options.delay || 500;
          }
  
          return this._runWithRetries(0, options.delay, options.retries);
      };
  
      /**
       * Internal method to identify the path to the command file.  It's essentially
       * unix which in JavaScript.
       * @private
       */
      ChildProcess.prototype._parseCommandPath = function _parseCommandPath (command) {
          var self = this;
  
          if (self._fileExists(command)) {
              return command;
          } else {
              var found = _.some(self._getPaths(), function (current) {
                  var target = path.resolve(current + '/' + command);
  
                  if (self._fileExists(target)) {
                      command = target;
  
                      return true;
                  }
              });
  
              return found ? command : null;
          }
      };
  
      /**
       * Internal method to verify a file exists and is not a directory.
       * @private
       */
      ChildProcess.prototype._fileExists = function _fileExists (file) {
          return fs.existsSync(file) && !fs.statSync(file).isDirectory();
      };
  
      /**
       * Internal method to get an array of directories in the users path.
       * @private
       */
      ChildProcess.prototype._getPaths = function _getPaths () {
          var path = process.env.path || process.env.Path || process.env.PATH;
          return path.split(':');
      };
  
      return ChildProcess;
  }