docs: function lookupConfig(keys, opts, cb) {
  
    if (!Array.isArray(keys)) {
      keys = [keys];
    }
    opts.prompt = opts.prompt || false;
  
    // parse values from configuration file if supplied
    var file = {};
    if (opts.file) {
      var content = this.lookupFile(opts.file);
      if (opts.file.match(/\.json$/)) {
        file.json = JSON.parse(content);
      } else if (opts.file.match(/\.ya?ml$/)) {
        file.yaml = yaml.load(content);
      } else {
        throw new Error('Configuration file extension is not supported');
      }
    }
  
    function lookup(key, cb) {
      if (process.env[key]) {
        cb(process.env[key]);
      } else if (file.json) {
        cb(file.json[key]);
      } else if (file.yaml) {
        cb(file.yaml[key]);
      } else {
        cb(undefined);
      }
    }
  
    // lookup for values in environment variables and configuration file
    var tasks = {};
    keys.forEach(function (key) {
      tasks[key] = function (cb) {
        lookup(key, function (result) {
          cb(null, result);
        });
      };
    });
  
    async.parallel(tasks, function (err, results) {
  
      if (opts.prompt) {
        // prompt users for any keys that don't yet have any value from
        // environment variables and configuration file
        var promptKeys = [];
        keys.forEach(function (key) {
          if (results[key] === undefined) {
            if (key.toLowerCase().indexOf('password') >= 0) {
              promptKeys.push({ name: key, hidden: true });
            } else {
              promptKeys.push(key);
            }
          }
        });
        if (promptKeys.length > 0) {
          prompt.get(promptKeys, function (err, promptResults) {
            results = _.extend(results, promptResults);
            cb(err, results);
          });
        } else {
          cb(err, results);
        }
      } else {
        cb(err, results);
      }
    });
  }