public function relationship($class, $type, $name, array $config = []) {
		$fieldName = $this->relationFieldName($type, $name);
		$config += compact('name', 'type', 'key', 'fieldName');
		$config['from'] = $class;

		return $this->_instance('relationship', $config + [
			'strategy' => function($rel) use ($config, $class, $name, $type) {
				if (isset($config['key'])) {
					return [];
				}
				$link = null;
				$hasLink = isset($config['link']);

				$result = [];
				$to = $rel->to();
				$local = $class::key();
				$className = $class::meta('name');

				$keys = [
					[$class, $name],
					[$class, Inflector::singularize($name)],
					[$to, Inflector::singularize($className)],
					[$to, $className]
				];
				foreach ($keys as $map) {
					list($on, $key) = $map;
					$key = lcfirst(Inflector::camelize($key));

					if (!$on::hasField($key)) {
						continue;
					}
					$join = ($on === $class) ? [$key => $on::key()] : [$local => $key];
					$result['key'] = $join;

					if (isset($config['link'])) {
						return $result;
					}
					$fieldType = $on::schema()->type($key);

					if ($fieldType === 'id' || $fieldType === 'MongoId') {
						$isArray = $on::schema()->is('array', $key);
						$link = $isArray ? $rel::LINK_KEY_LIST : $rel::LINK_KEY;
						break;
					}
				}
				if (!$link && !$hasLink) {
					$link = ($type === "belongsTo") ? $rel::LINK_CONTAINED : $rel::LINK_EMBEDDED;
				}
				return $result + ($hasLink ? [] : compact('link'));
			}
		]);
	}