public static function translate($key, $params = [], $language = null, Viewmodel $viewmodel = null) {
		
		$identifier = null;

		if(null !== $viewmodel) {
			$identifier = static :: load($viewmodel);
		}

		if(null === $key) {
			$key = '';
		}

		//Check if key is a string
		if(false === is_string($key)) {
			return trigger_error(sprintf('Argument 1 passed to %s() must be of the type string, "%s" given', __METHOD__, gettype($key)), E_USER_ERROR);
		}

		//Check if params is an array
		if(null !== $params && false === is_array($params)) {
			return trigger_error(sprintf('Argument 2 passed to %s() must be of the type array, "%s" given', __METHOD__, gettype($params)), E_USER_ERROR);
		}

		//Check if language is a string
		if(null !== $language && false === is_string($language)) {
			return trigger_error(sprintf('Argument 3 passed to %s() must be of the type string, "%s" given', __METHOD__, gettype($language)), E_USER_ERROR);
		}

		//Set default language if non given
		if(null === $language) {
			$language = static :: $language;
		}

		//If identifier is known (usually with a viewmodel as last param)
		if(null !== $identifier) {

			if(true === isset(static :: $translations[$identifier], static :: $translations[$identifier][$language])) {

				if(true === isset(static :: $translations[$identifier][$language][$key])) {
					return vsprintf(static :: $translations[$identifier][$language][$key], $params);
				}
			}
		}

		//Check the full resource for the translation
		foreach(static :: $translations as $translation) {

			if(true === isset($translation[$language][$key])) {
				return vsprintf($translation[$language][$key], $params);
			}
		}

		//No translation found
		return vsprintf($key, $params);
	}