text: 'use strict';
  var fs   = require('fs')
  var ini  = require('ini')
  var path = require('path')
  var stripJsonComments = require('strip-json-comments')
  
  var parse = exports.parse = function (content) {
  
    //if it ends in .json or starts with { then it must be json.
    //must be done this way, because ini accepts everything.
    //can't just try and parse it and let it throw if it's not ini.
    //everything is ini. even json with a syntax error.
  
    if(/^\s*{/.test(content))
      return JSON.parse(stripJsonComments(content))
    return ini.parse(content)
  
  }
  
  var file = exports.file = function () {
    var args = [].slice.call(arguments).filter(function (arg) { return arg != null })
  
    //path.join breaks if it's a not a string, so just skip this.
    for(var i in args)
      if('string' !== typeof args[i])
        return
  
    var file = path.join.apply(null, args)
    var content
    try {
      return fs.readFileSync(file,'utf-8')
    } catch (err) {
      return
    }
  }
  
  var json = exports.json = function () {
    var content = file.apply(null, arguments)
    return content ? parse(content) : null
  }
  
  var env = exports.env = function (prefix, env) {
    env = env || process.env
    var obj = {}
    var l = prefix.length
    for(var k in env) {
      if((k.indexOf(prefix)) === 0) {
  
        var keypath = k.substring(l).split('__')
  
        // Trim empty strings from keypath array
        var _emptyStringIndex
        while ((_emptyStringIndex=keypath.indexOf('')) > -1) {
          keypath.splice(_emptyStringIndex, 1)
        }
  
        var cursor = obj
        keypath.forEach(function _buildSubObj(_subkey,i){
  
          // (check for _subkey first so we ignore empty strings)
          // (check for cursor to avoid assignment to primitive objects)
          if (!_subkey || typeof cursor !== 'object')
            return
  
          // If this is the last key, just stuff the value in there
          // Assigns actual value from env variable to final key
          // (unless it's just an empty string- in that case use the last valid key)
          if (i === keypath.length-1)
            cursor[_subkey] = env[k]
  
  
          // Build sub-object if nothing already exists at the keypath
          if (cursor[_subkey] === undefined)
            cursor[_subkey] = {}
  
          // Increment cursor used to track the object at the current depth
          cursor = cursor[_subkey]
  
        })
  
      }
  
    }
  
    return obj
  }
  
  var find = exports.find = function () {
    var rel = path.join.apply(null, [].slice.call(arguments))
  
    function find(start, rel) {
      var file = path.join(start, rel)
      try {
        fs.statSync(file)
        return file
      } catch (err) {
        if(path.dirname(start) !== start) // root
          return find(path.dirname(start), rel)
      }
    }
    return find(process.cwd(), rel)
  }
  
  