protected static function _update($export) {
		$export += [
			'data' => [],
			'update' => [],
			'remove' => [],
			'rename' => [],
			'key' => ''
		];
		$path = $export['key'] ? "{$export['key']}." : "";
		$result = ['update' => [], 'remove' => []];
		$left = static::_diff($export['data'], $export['update']);
		$right = static::_diff($export['update'], $export['data']);

		$objects = array_filter($export['update'], function($value) {
			return (is_object($value) && method_exists($value, 'export'));
		});
		array_map(function($key) use (&$left) { unset($left[$key]); }, array_keys($right));

		foreach ($left as $key => $value) {
			$result = static::_append($result, "{$path}{$key}", $value, 'remove');
		}
		$update = $right + $objects;

		foreach ($update as $key => $value) {
			$original = $export['data'];
			$isArray = is_object($value) && $value instanceof static::$_classes['set'];

			$options = [
				'indexed' => null,
				'handlers' => [
					'MongoDate' => function($value) { return $value; },
					'MongoId' => function($value) { return $value; }
				]
			];

			if ($isArray) {
				$newValue = $value->to('array', $options);
				$originalValue = null;
				$shouldConvert = (isset($original[$key]) && (
					$original[$key] instanceof static::$_classes['set'] ||
					$original[$key] instanceof static::$_classes['entity']
				));
				if ($shouldConvert) {
					$originalValue = $original[$key]->to('array', $options);
				}
				if ($newValue !== $originalValue) {
					$value = $newValue;
				}
			}
			$result = static::_append($result, "{$path}{$key}", $value, 'update');
		}
		return array_filter($result);
	}