code: function readData(id, force) {
      if (typeof id === 'undefined') {
        if (!force && options.cacheValues) {
          return Promise.resolve(cachedData);
        }
  
        return readKeys(force).then(function(keys) {
          var promises = [];
          var data = {};
  
          keys.forEach(function(key) {
            promises.push(readData(key).then(function(keyData) {
              data[key] = keyData;
            }));
          });
  
          return Promise.all(promises).then(function() {
            return Promise.resolve(data);
          });
        });
      } else {
        // Return the cached value if we are caching values
        if (!force && options.cacheValues) {
          return Promise.resolve(cachedData[id]);
        }
  
        // Check if we have a key for the data if we have cached the keys
        if (!force && options.cacheKeys && cachedKeys.indexOf(id) === -1) {
          return Promise.resolve(undefined);
        }
  
        var filename = getFilename(id);
  
        // Check if file exists
        return access(filename, fs.R_OK | fs.W_OK).then(function() {
          return readFile(filename).then(function(buffer) {
            try {
              return Promise.resolve(JSON.parse(buffer));
            } catch (err) {
              return Promise.reject(err);
            }
          });
        }, function(err) {
          if (err.code === 'ENOENT') {
            return Promise.resolve(undefined);
          } else {
            return Promise.reject(err);
          }
        });
      }
    }
docs: @private
  Retreives the value for a given id from the associated file
  
  @param {String} [id] Id of parameter to get filename for
  @param {boolean} [force] Whether or not to force a reread of the data
  from the file
  
  @returns {Promise} A promise that will resolve to the data