(function() {
  var getValueAtKeyPath, hasKeyPath, setValueAtKeyPath, splitKeyPath;

  hasKeyPath = function(object, keyPath) {
    var key, keys, _i, _len;
    keys = splitKeyPath(keyPath);
    for (_i = 0, _len = keys.length; _i < _len; _i++) {
      key = keys[_i];
      if (!(object != null ? object.hasOwnProperty(key) : void 0)) {
        return false;
      }
      object = object[key];
    }
    return true;
  };

  getValueAtKeyPath = function(object, keyPath) {
    var key, keys, _i, _len;
    keys = splitKeyPath(keyPath);
    for (_i = 0, _len = keys.length; _i < _len; _i++) {
      key = keys[_i];
      object = object[key];
      if (object == null) {
        return object;
      }
    }
    return object;
  };

  setValueAtKeyPath = function(object, keyPath, value) {
    var key, keys;
    keys = splitKeyPath(keyPath);
    while (keys.length > 1) {
      key = keys.shift();
      if (object[key] == null) {
        object[key] = {};
      }
      object = object[key];
    }
    return object[keys.shift()] = value;
  };

  splitKeyPath = function(keyPath) {
    var char, i, keyPathArray, startIndex, _i, _len;
    if (keyPath == null) {
      return [];
    }
    startIndex = 0;
    keyPathArray = [];
    for (i = _i = 0, _len = keyPath.length; _i < _len; i = ++_i) {
      char = keyPath[i];
      if (char === '.' && (i === 0 || keyPath[i - 1] !== '\\')) {
        keyPathArray.push(keyPath.substring(startIndex, i));
        startIndex = i + 1;
      }
    }
    keyPathArray.push(keyPath.substr(startIndex, keyPath.length));
    return keyPathArray;
  };

  module.exports = {
    hasKeyPath: hasKeyPath,
    getValueAtKeyPath: getValueAtKeyPath,
    setValueAtKeyPath: setValueAtKeyPath,
    splitKeyPath: splitKeyPath
  };

}).call(this);
