Add/update a path off an object
@param {!Object} obj
@param {*} value
@param {Array<string|number>} path
@param {number} [i]
@throws {Error}
@private
function add(obj, path, value, i) {
	i = i || 0

	var key = path[i],
		last = i === path.length - 1

	if (!obj || typeof obj !== 'object') {
		throw new Error('Can\'t add key ' + key + ' to non-object')
	}

	if (Array.isArray(obj)) {
		if (typeof key !== 'number') {
			obj.forEach(function (each) {
				add(each, path, value, i)
			})
		} else if (key >= 0 && key <= obj.length) {
			if (last) {
				obj[key] = value
			} else {
				add(obj[key], path, value, i + 1)
			}
		} else {
			throw new Error('Can\'t add index ' + key + ' to an array with ' + obj.length + ' elements')
		}
	} else {
		if (typeof key !== 'string') {
			throw new Error('Can\'t add the numeric key ' + key + ' to an object')
		} else {
			if (last) {
				obj[key] = value
			} else {
				if (!(key in obj)) {
					obj[key] = Object.create(null)
				}
				add(obj[key], path, value, i + 1)
			}
		}
	}
}