diff --git a/framework/YiiBase.php b/framework/YiiBase.php
index d01648c..be59c16 100644
--- a/framework/YiiBase.php
+++ b/framework/YiiBase.php
@@ -507,9 +507,6 @@ class YiiBase
 	 * i.e., the message returned will be chosen from a few candidates according to the given
 	 * number value. This feature is mainly used to solve plural format issue in case
 	 * a message has different plural forms in some languages.
-	 * @param string $category message category. Please use only word letters. Note, category 'yii' is
-	 * reserved for Yii framework core code use. See {@link CPhpMessageSource} for
-	 * more interpretation about message category.
 	 * @param string $message the original message
 	 * @param array $params parameters to be applied to the message using <code>strtr</code>.
 	 * The first parameter can be a number without key.
@@ -517,62 +514,12 @@ class YiiBase
 	 * an appropriate message translation.
 	 * You can pass parameter for {@link CChoiceFormat::format}
 	 * or plural forms format without wrapping it with array.
-	 * @param string $source which message source application component to use.
-	 * Defaults to null, meaning using 'coreMessages' for messages belonging to
-	 * the 'yii' category and using 'messages' for the rest messages.
 	 * @param string $language the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
 	 * @return string the translated message
 	 * @see CMessageSource
 	 */
-	public static function t($category, $message, $params = array(), $source = null, $language = null)
+	public static function t($message, $params = array(), $language = null)
 	{
-		// todo;
-		return $params !== array() ? strtr($message, $params) : $message;
-		if (self::$application !== null)
-		{
-			if ($source === null)
-					{
-						$source = $category === 'yii' ? 'coreMessages' : 'messages';
-					}
-			if (($source = self::$application->getComponent($source)) !== null)
-					{
-						$message = $source->translate($category, $message, $language);
-					}
-		}
-		if ($params === array())
-				{
-					return $message;
-				}
-		if (!is_array($params))
-				{
-					$params = array($params);
-				}
-		if (isset($params[0])) // number choice
-		{
-			if (strpos($message, '|') !== false)
-			{
-				if (strpos($message, '#') === false)
-				{
-					$chunks = explode('|', $message);
-					$expressions = self::$application->getLocale($language)->getPluralRules();
-					if ($n = min(count($chunks), count($expressions)))
-					{
-						for ($i = 0; $i < $n; $i++)
-								{
-									$chunks[$i] = $expressions[$i] . '#' . $chunks[$i];
-								}
-
-						$message = implode('|', $chunks);
-					}
-				}
-				$message = CChoiceFormat::format($message, $params[0]);
-			}
-			if (!isset($params['{n}']))
-					{
-						$params['{n}'] = $params[0];
-					}
-			unset($params[0]);
-		}
-		return $params !== array() ? strtr($message, $params) : $message;
+		Yii::$application->getI18N()->translate($message, $params, $language);
 	}
 }
diff --git a/framework/base/Application.php b/framework/base/Application.php
index cd77f1f..e4c1333 100644
--- a/framework/base/Application.php
+++ b/framework/base/Application.php
@@ -30,10 +30,6 @@ use yii\util\FileHelper;
  *   persistence method. This application component is dynamically loaded when needed.</li>
  * <li>{@link getCache cache}: provides caching feature. This application component is
  *   disabled by default.</li>
- * <li>{@link getMessages messages}: provides the message source for translating
- *   application messages. This application component is dynamically loaded when needed.</li>
- * <li>{@link getCoreMessages coreMessages}: provides the message source for translating
- *   Yii framework messages. This application component is dynamically loaded when needed.</li>
  * </ul>
  *
  * Application will undergo the following life cycles when processing a user request:
@@ -57,23 +53,28 @@ class Application extends Module
 	const EVENT_BEFORE_REQUEST = 'beforeRequest';
 	const EVENT_AFTER_REQUEST = 'afterRequest';
 	/**
-	 * @var string the application name. Defaults to 'My Application'.
+	 * @var string the application name.
 	 */
 	public $name = 'My Application';
 	/**
-	 * @var string the version of this application. Defaults to '1.0'.
+	 * @var string the version of this application.
 	 */
 	public $version = '1.0';
 	/**
-	 * @var string the charset currently used for the application. Defaults to 'UTF-8'.
+	 * @var string the charset currently used for the application.
 	 */
 	public $charset = 'UTF-8';
 	/**
+	 * @var string the language that is meant to be used for end users.
+	 * @see sourceLanguage
+	 */
+	public $language = 'en_US';
+	/**
 	 * @var string the language that the application is written in. This mainly refers to
-	 * the language that the messages and view files are in. Defaults to 'en_us' (US English).
+	 * the language that the messages and view files are written in.
 	 * @see language
 	 */
-	public $sourceLanguage = 'en_us';
+	public $sourceLanguage = 'en_US';
 	/**
 	 * @var array IDs of the components that need to be loaded when the application starts.
 	 */
@@ -213,29 +214,6 @@ class Application extends Module
 	}
 
 	/**
-	 * Returns the language that the end user is using.
-	 * @return string the language that the user is using (e.g. 'en_US', 'zh_CN').
-	 * Defaults to the value of [[sourceLanguage]].
-	 */
-	public function getLanguage()
-	{
-		return $this->_language === null ? $this->sourceLanguage : $this->_language;
-	}
-
-	/**
-	 * Specifies which language the end user is using.
-	 * This is the language that the application should use to display to end users.
-	 * By default, [[language]] and [[sourceLanguage]] are the same.
-	 * Do not set this property unless your application needs to support multiple languages.
-	 * @param string $language the user language (e.g. 'en_US', 'zh_CN').
-	 * If it is null, the [[sourceLanguage]] will be used.
-	 */
-	public function setLanguage($language)
-	{
-		$this->_language = $language;
-	}
-
-	/**
 	 * Returns the time zone used by this application.
 	 * This is a simple wrapper of PHP function date_default_timezone_get().
 	 * @return string the time zone used by this application.
@@ -295,23 +273,6 @@ class Application extends Module
 	//		return $this->getLocale()->getDateFormatter();
 	//	}
 	//
-	//	/**
-	//	 * Returns the core message translations component.
-	//	 * @return \yii\i18n\MessageSource the core message translations
-	//	 */
-	//	public function getCoreMessages()
-	//	{
-	//		return $this->getComponent('coreMessages');
-	//	}
-	//
-	//	/**
-	//	 * Returns the application message translations component.
-	//	 * @return \yii\i18n\MessageSource the application message translations
-	//	 */
-	//	public function getMessages()
-	//	{
-	//		return $this->getComponent('messages');
-	//	}
 
 	/**
 	 * Returns the database connection component.
@@ -368,6 +329,15 @@ class Application extends Module
 	}
 
 	/**
+	 * Returns the internationalization (i18n) component
+	 * @return \yii\i18n\I18N the internationalization component
+	 */
+	public function getI18N()
+	{
+		return $this->getComponent('i18n');
+	}
+
+	/**
 	 * Sets default path aliases.
 	 */
 	public function registerDefaultAliases()
@@ -387,19 +357,14 @@ class Application extends Module
 			'errorHandler' => array(
 				'class' => 'yii\base\ErrorHandler',
 			),
-			'coreMessages' => array(
-				'class' => 'yii\i18n\PhpMessageSource',
-				'language' => 'en_us',
-				'basePath' => '@yii/messages',
-			),
-			'messages' => array(
-				'class' => 'yii\i18n\PhpMessageSource',
+			'i18n' => array(
+				'class' => 'yii\i18n\I18N',
 			),
 			'securityManager' => array(
 				'class' => 'yii\base\SecurityManager',
 			),
-			'urlManager' => array(
-				'class' => 'yii\web\UrlManager',
+			'translator' => array(
+				'class' => 'yii\i18n\Translator',
 			),
 		));
 	}
diff --git a/framework/base/Controller.php b/framework/base/Controller.php
index f9cf399..15681e8 100644
--- a/framework/base/Controller.php
+++ b/framework/base/Controller.php
@@ -177,7 +177,7 @@ class Controller extends Component
 		}
 
 		if ($missing !== array()) {
-			throw new InvalidRequestException(Yii::t('yii', 'Missing required parameters: {params}', array(
+			throw new InvalidRequestException(Yii::t('yii:Missing required parameters: {params}', array(
 				'{params}' => implode(', ', $missing),
 			)));
 		}
diff --git a/framework/base/Exception.php b/framework/base/Exception.php
index db77028..d9cb77a 100644
--- a/framework/base/Exception.php
+++ b/framework/base/Exception.php
@@ -22,7 +22,7 @@ class Exception extends \Exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Exception');
+		return \Yii::t('yii:Exception');
 	}
 }
 
diff --git a/framework/base/HttpException.php b/framework/base/HttpException.php
index 378b56a..e23ff09 100644
--- a/framework/base/HttpException.php
+++ b/framework/base/HttpException.php
@@ -104,6 +104,6 @@ class HttpException extends UserException
 		if(isset($httpCodes[$this->statusCode]))
 			return $httpCodes[$this->statusCode];
 		else
-			return \Yii::t('yii', 'Error');
+			return \Yii::t('yii:Error');
 	}
 }
diff --git a/framework/base/InvalidCallException.php b/framework/base/InvalidCallException.php
index a1df021..ab9de67 100644
--- a/framework/base/InvalidCallException.php
+++ b/framework/base/InvalidCallException.php
@@ -15,14 +15,14 @@ namespace yii\base;
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class InvalidCallException extends \Exception
+class InvalidCallException extends Exception
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Invalid Call');
+		return \Yii::t('yii:Invalid Call');
 	}
 }
 
diff --git a/framework/base/InvalidConfigException.php b/framework/base/InvalidConfigException.php
index 3c100d1..97cdc8e 100644
--- a/framework/base/InvalidConfigException.php
+++ b/framework/base/InvalidConfigException.php
@@ -15,14 +15,14 @@ namespace yii\base;
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class InvalidConfigException extends \Exception
+class InvalidConfigException extends Exception
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Invalid Configuration');
+		return \Yii::t('yii:Invalid Configuration');
 	}
 }
 
diff --git a/framework/base/InvalidRequestException.php b/framework/base/InvalidRequestException.php
index dddb35e..428d008 100644
--- a/framework/base/InvalidRequestException.php
+++ b/framework/base/InvalidRequestException.php
@@ -22,7 +22,7 @@ class InvalidRequestException extends UserException
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Invalid Request');
+		return \Yii::t('yii:Invalid Request');
 	}
 }
 
diff --git a/framework/base/InvalidRouteException.php b/framework/base/InvalidRouteException.php
index 0d5a9b5..929221c 100644
--- a/framework/base/InvalidRouteException.php
+++ b/framework/base/InvalidRouteException.php
@@ -22,7 +22,7 @@ class InvalidRouteException extends UserException
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Invalid Route');
+		return \Yii::t('yii:Invalid Route');
 	}
 }
 
diff --git a/framework/base/NotSupportedException.php b/framework/base/NotSupportedException.php
index 56e7e36..b7efed4 100644
--- a/framework/base/NotSupportedException.php
+++ b/framework/base/NotSupportedException.php
@@ -15,14 +15,14 @@ namespace yii\base;
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class NotSupportedException extends \Exception
+class NotSupportedException extends Exception
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Not Supported');
+		return \Yii::t('yii:Not Supported');
 	}
 }
 
diff --git a/framework/base/SecurityManager.php b/framework/base/SecurityManager.php
index 441b908..04be15c 100644
--- a/framework/base/SecurityManager.php
+++ b/framework/base/SecurityManager.php
@@ -79,7 +79,7 @@ class SecurityManager extends Component
 		if (!empty($value)) {
 			$this->_validationKey = $value;
 		} else {
-			throw new CException(Yii::t('yii', 'SecurityManager.validationKey cannot be empty.'));
+			throw new CException(Yii::t('yii:SecurityManager.validationKey cannot be empty.'));
 		}
 	}
 
@@ -112,7 +112,7 @@ class SecurityManager extends Component
 		if (!empty($value)) {
 			$this->_encryptionKey = $value;
 		} else {
-			throw new CException(Yii::t('yii', 'SecurityManager.encryptionKey cannot be empty.'));
+			throw new CException(Yii::t('yii:SecurityManager.encryptionKey cannot be empty.'));
 		}
 	}
 
@@ -191,12 +191,12 @@ class SecurityManager extends Component
 			}
 
 			if ($module === false) {
-				throw new CException(Yii::t('yii', 'Failed to initialize the mcrypt module.'));
+				throw new CException(Yii::t('yii:Failed to initialize the mcrypt module.'));
 			}
 
 			return $module;
 		} else {
-			throw new CException(Yii::t('yii', 'SecurityManager requires PHP mcrypt extension to be loaded in order to use data encryption feature.'));
+			throw new CException(Yii::t('yii:SecurityManager requires PHP mcrypt extension to be loaded in order to use data encryption feature.'));
 		}
 	}
 
diff --git a/framework/base/UnknownMethodException.php b/framework/base/UnknownMethodException.php
index 459f791..0cad676 100644
--- a/framework/base/UnknownMethodException.php
+++ b/framework/base/UnknownMethodException.php
@@ -15,14 +15,14 @@ namespace yii\base;
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class UnknownMethodException extends \Exception
+class UnknownMethodException extends Exception
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Unknown Method');
+		return \Yii::t('yii:Unknown Method');
 	}
 }
 
diff --git a/framework/base/UnknownPropertyException.php b/framework/base/UnknownPropertyException.php
index de8de1c..a226f84 100644
--- a/framework/base/UnknownPropertyException.php
+++ b/framework/base/UnknownPropertyException.php
@@ -15,14 +15,14 @@ namespace yii\base;
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class UnknownPropertyException extends \Exception
+class UnknownPropertyException extends Exception
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Unknown Property');
+		return \Yii::t('yii:Unknown Property');
 	}
 }
 
diff --git a/framework/base/UrlManager.php b/framework/base/UrlManager.php
index 3de8807..e90f08f 100644
--- a/framework/base/UrlManager.php
+++ b/framework/base/UrlManager.php
@@ -366,7 +366,7 @@ class UrlManager extends Component
 					return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
 			}
 			if($this->useStrictParsing)
-				throw new HttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
+				throw new HttpException(404,Yii::t('yii:Unable to resolve the request "{route}".',
 					array('{route}'=>$pathInfo)));
 			else
 				return $pathInfo;
@@ -502,7 +502,7 @@ class UrlManager extends Component
 		if($value===self::PATH_FORMAT || $value===self::GET_FORMAT)
 			$this->_urlFormat=$value;
 		else
-			throw new CException(Yii::t('yii','CUrlManager.UrlFormat must be either "path" or "get".'));
+			throw new CException(Yii::t('yii:CUrlManager.UrlFormat must be either "path" or "get".'));
 	}
 }
 
@@ -685,7 +685,7 @@ class CUrlRule extends CBaseUrlRule
 			$this->routePattern='/^'.strtr($this->route,$tr2).'$/u';
 
 		if(YII_DEBUG && @preg_match($this->pattern,'test')===false)
-			throw new CException(Yii::t('yii','The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.',
+			throw new CException(Yii::t('yii:The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.',
 				array('{route}'=>$route,'{pattern}'=>$pattern)));
 	}
 
diff --git a/framework/console/Application.php b/framework/console/Application.php
index 2f91d5b..7a8de43 100644
--- a/framework/console/Application.php
+++ b/framework/console/Application.php
@@ -93,7 +93,7 @@ class Application extends \yii\base\Application
 		if ($request->getIsConsoleRequest()) {
 			return $this->runAction($request->route, $request->params);
 		} else {
-			throw new Exception(\Yii::t('yii', 'this script must be run from the command line.'));
+			throw new Exception(\Yii::t('yii:this script must be run from the command line.'));
 		}
 	}
 
@@ -112,7 +112,7 @@ class Application extends \yii\base\Application
 		try {
 			return parent::runAction($route, $params);
 		} catch (InvalidRouteException $e) {
-			throw new Exception(\Yii::t('yii', 'Unknown command "{command}".', array('{command}' => $route)));
+			throw new Exception(\Yii::t('yii:Unknown command "{command}".', array('{command}' => $route)));
 		}
 	}
 
diff --git a/framework/console/Controller.php b/framework/console/Controller.php
index f51588f..b3e9ff7 100644
--- a/framework/console/Controller.php
+++ b/framework/console/Controller.php
@@ -85,7 +85,7 @@ class Controller extends \yii\base\Controller
 		$args = isset($params[Request::ANONYMOUS_PARAMS]) ? $params[Request::ANONYMOUS_PARAMS] : array();
 		unset($params[Request::ANONYMOUS_PARAMS]);
 		if ($params !== array()) {
-			throw new Exception(Yii::t('yii', 'Unknown options: {params}', array(
+			throw new Exception(Yii::t('yii:Unknown options: {params}', array(
 				'{params}' => implode(', ', array_keys($params)),
 			)));
 		}
@@ -109,7 +109,7 @@ class Controller extends \yii\base\Controller
 		}
 
 		if ($missing !== array()) {
-			throw new Exception(Yii::t('yii', 'Missing required arguments: {params}', array(
+			throw new Exception(Yii::t('yii:Missing required arguments: {params}', array(
 				'{params}' => implode(', ', $missing),
 			)));
 		}
diff --git a/framework/console/Exception.php b/framework/console/Exception.php
index 63daba3..052030b 100644
--- a/framework/console/Exception.php
+++ b/framework/console/Exception.php
@@ -9,20 +9,22 @@
 
 namespace yii\console;
 
+use yii\base\UserException;
+
 /**
  * Exception represents an exception caused by incorrect usage of a console command.
  *
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
-class Exception extends \yii\base\UserException
+class Exception extends UserException
 {
 	/**
 	 * @return string the user-friendly name of this exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Error');
+		return \Yii::t('yii:Error');
 	}
 }
 
diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php
index 147fde0..7e2eab9 100644
--- a/framework/console/controllers/HelpController.php
+++ b/framework/console/controllers/HelpController.php
@@ -57,7 +57,7 @@ class HelpController extends Controller
 		if ($command !== null) {
 			$result = Yii::$application->createController($command);
 			if ($result === false) {
-				throw new Exception(Yii::t('yii', 'No help for unknown command "{command}".', array(
+				throw new Exception(Yii::t('yii:No help for unknown command "{command}".', array(
 					'{command}' => $command,
 				)));
 			}
@@ -241,7 +241,7 @@ class HelpController extends Controller
 	{
 		$action = $controller->createAction($actionID);
 		if ($action === null) {
-			throw new Exception(Yii::t('yii', 'No help for unknown sub-command "{command}".', array(
+			throw new Exception(Yii::t('yii:No help for unknown sub-command "{command}".', array(
 				'{command}' => rtrim($controller->getUniqueId() . '/' . $actionID, '/'),
 			)));
 		}
diff --git a/framework/db/Exception.php b/framework/db/Exception.php
index 209dc40..1c4196f 100644
--- a/framework/db/Exception.php
+++ b/framework/db/Exception.php
@@ -40,6 +40,6 @@ class Exception extends \yii\base\Exception
 	 */
 	public function getName()
 	{
-		return \Yii::t('yii', 'Database Exception');
+		return \Yii::t('yii:Database Exception');
 	}
 }
\ No newline at end of file
diff --git a/framework/i18n/I18N.php b/framework/i18n/I18N.php
new file mode 100644
index 0000000..99a4e69
--- /dev/null
+++ b/framework/i18n/I18N.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace yii\i18n;
+
+use Yii;
+use yii\base\Component;
+
+class I18N extends Component
+{
+	public function translate($message, $params = array(), $language = null)
+	{
+		if ($language === null) {
+			$language = Yii::$application->language;
+		}
+
+		if (preg_match('/^([\w\-]+):(.*)/', $message, $matches)) {
+			$category = $matches[1];
+			$message = $matches[2];
+		} else {
+			$category = 'app';
+		}
+
+		$message = $this->getSource($category)->translate($category, $message, $language);
+
+		if (!is_array($params)) {
+			$params = array($params);
+		}
+
+		if (isset($params[0])) {
+			$message = $this->getPluralFormat($message, $params[0], $language);
+			if (!isset($params['{n}'])) {
+				$params['{n}'] = $params[0];
+			}
+			unset($params[0]);
+		}
+
+		return $params === array() ? $message : strtr($message, $params);
+	}
+
+	public function getLocale($language)
+	{
+
+	}
+
+	public function getSource($category)
+	{
+		return $category === 'yii' ? $this->getMessages() : $this->getCoreMessages();
+	}
+
+	private $_coreMessages;
+	private $_messages;
+
+	public function getCoreMessages()
+	{
+		if (is_object($this->_coreMessages)) {
+			return $this->_coreMessages;
+		} elseif ($this->_coreMessages === null) {
+			return $this->_coreMessages = new PhpMessageSource(array(
+				'sourceLanguage' => 'en_US',
+				'basePath' => '@yii/messages',
+			));
+		} else {
+			return $this->_coreMessages = Yii::createObject($this->_coreMessages);
+		}
+	}
+
+	public function setCoreMessages($config)
+	{
+		$this->_coreMessages = $config;
+	}
+
+	public function getMessages()
+	{
+		if (is_object($this->_messages)) {
+			return $this->_messages;
+		} elseif ($this->_messages === null) {
+			return $this->_messages = new PhpMessageSource(array(
+				'sourceLanguage' => 'en_US',
+				'basePath' => '@app/messages',
+			));
+		} else {
+			return $this->_messages = Yii::createObject($this->_messages);
+		}
+	}
+
+	public function setMessages($config)
+	{
+		$this->_messages = $config;
+	}
+
+	protected function getPluralFormat($message, $number, $language)
+	{
+		if (strpos($message, '|') === false) {
+			return $message;
+		}
+		$chunks = explode('|', $message);
+		$rules = $this->getLocale($language)->getPluralRules();
+		foreach ($rules as $i => $rule) {
+			if (isset($chunks[$i]) && self::evaluate($rule, $number)) {
+				return $chunks[$i];
+			}
+		}
+		$n = count($rules);
+		return isset($chunks[$n]) ? $chunks[$n] : $chunks[0];
+	}
+
+	/**
+	 * Evaluates a PHP expression with the given number value.
+	 * @param string $expression the PHP expression
+	 * @param mixed $n the number value
+	 * @return boolean the expression result
+	 */
+	protected static function evaluate($expression, $n)
+	{
+		return @eval("return $expression;");
+	}
+}
diff --git a/framework/i18n/MessageSource.php b/framework/i18n/MessageSource.php
new file mode 100644
index 0000000..17a5b00
--- /dev/null
+++ b/framework/i18n/MessageSource.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * MessageSource class file.
+ *
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+namespace yii\i18n;
+
+use Yii;
+use yii\base\Component;
+
+/**
+ * MessageSource is the base class for message translation repository classes.
+ *
+ * A message source is an application component that provides message internationalization (i18n).
+ * It stores messages translated in different languages and provides
+ * these translated versions when requested.
+ *
+ * A concrete class must implement {@link loadMessages} or override {@link translateMessage}.
+ *
+ * @property string $language The language that the source messages are written in.
+ * Defaults to {@link CApplication::language application language}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @since 2.0
+ */
+abstract class MessageSource extends Component
+{
+	/**
+	 * @var boolean whether to force message translation when the source and target languages are the same.
+	 * Defaults to false, meaning translation is only performed when source and target languages are different.
+	 */
+	public $forceTranslation = false;
+	public $sourceLanguage;
+
+	private $_messages = array();
+
+	public function init()
+	{
+		parent::init();
+		if ($this->sourceLanguage === null) {
+			$this->sourceLanguage = Yii::$application->sourceLanguage;
+		}
+	}
+
+	/**
+	 * Loads the message translation for the specified language and category.
+	 * @param string $category the message category
+	 * @param string $language the target language
+	 * @return array the loaded messages
+	 */
+	abstract protected function loadMessages($category, $language);
+
+	/**
+	 * Translates a message to the specified language.
+	 *
+	 * Note, if the specified language is the same as
+	 * the {@link getLanguage source message language}, messages will NOT be translated.
+	 *
+	 * If the message is not found in the translations, an {@link onMissingTranslation}
+	 * event will be raised. Handlers can mark this message or do some
+	 * default handling. The {@link CMissingTranslationEvent::message}
+	 * property of the event parameter will be returned.
+	 *
+	 * @param string $category the message category
+	 * @param string $message the message to be translated
+	 * @param string $language the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
+	 * @return string the translated message (or the original message if translation is not needed)
+	 */
+	public function translate($category, $message, $language)
+	{
+		if ($this->forceTranslation || $language !== $this->sourceLanguage) {
+			return $this->translateMessage($category, $message, $language);
+		} else {
+			return $message;
+		}
+	}
+
+	/**
+	 * Translates the specified message.
+	 * If the message is not found, an {@link onMissingTranslation}
+	 * event will be raised.
+	 * @param string $category the category that the message belongs to
+	 * @param string $message the message to be translated
+	 * @param string $language the target language
+	 * @return string the translated message
+	 */
+	protected function translateMessage($category, $message, $language)
+	{
+		$key = $language . '/' . $category;
+		if (!isset($this->_messages[$key])) {
+			$this->_messages[$key] = $this->loadMessages($category, $language);
+		}
+		if (isset($this->_messages[$key][$message]) && $this->_messages[$key][$message] !== '') {
+			return $this->_messages[$key][$message];
+		} elseif ($this->hasEventHandler('onMissingTranslation')) {
+			$event = new CMissingTranslationEvent($this, $category, $message, $language);
+			$this->onMissingTranslation($event);
+			return $event->message;
+		} else {
+			return $message;
+		}
+	}
+
+	/**
+	 * Raised when a message cannot be translated.
+	 * Handlers may log this message or do some default handling.
+	 * The {@link CMissingTranslationEvent::message} property
+	 * will be returned by {@link translateMessage}.
+	 * @param CMissingTranslationEvent $event the event parameter
+	 */
+	public function onMissingTranslation($event)
+	{
+		$this->raiseEvent('onMissingTranslation', $event);
+	}
+}
+
+
+/**
+ * CMissingTranslationEvent represents the parameter for the {@link MessageSource::onMissingTranslation onMissingTranslation} event.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @package system.i18n
+ * @since 1.0
+ */
+class CMissingTranslationEvent extends CEvent
+{
+	/**
+	 * @var string the message to be translated
+	 */
+	public $message;
+	/**
+	 * @var string the category that the message belongs to
+	 */
+	public $category;
+	/**
+	 * @var string the ID of the language that the message is to be translated to
+	 */
+	public $language;
+
+	/**
+	 * Constructor.
+	 * @param mixed $sender sender of this event
+	 * @param string $category the category that the message belongs to
+	 * @param string $message the message to be translated
+	 * @param string $language the ID of the language that the message is to be translated to
+	 */
+	public function __construct($sender, $category, $message, $language)
+	{
+		parent::__construct($sender);
+		$this->message = $message;
+		$this->category = $category;
+		$this->language = $language;
+	}
+}
diff --git a/framework/i18n/PhpMessageSource.php b/framework/i18n/PhpMessageSource.php
new file mode 100644
index 0000000..4f8511f
--- /dev/null
+++ b/framework/i18n/PhpMessageSource.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * PhpMessageSource class file.
+ *
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+namespace yii\i18n;
+
+/**
+ * PhpMessageSource represents a message source that stores translated messages in PHP scripts.
+ *
+ * PhpMessageSource uses PHP files and arrays to keep message translations.
+ * <ul>
+ * <li>All translations are saved under the {@link basePath} directory.</li>
+ * <li>Translations in one language are kept as PHP files under an individual subdirectory
+ *   whose name is the same as the language ID. Each PHP file contains messages
+ *   belonging to the same category, and the file name is the same as the category name.</li>
+ * <li>Within a PHP file, an array of (source, translation) pairs is returned.
+ * For example:
+ * <pre>
+ * return array(
+ *     'original message 1' => 'translated message 1',
+ *     'original message 2' => 'translated message 2',
+ * );
+ * </pre>
+ * </li>
+ * </ul>
+ * When {@link cachingDuration} is set as a positive number, message translations will be cached.
+ *
+ * Messages for an extension class (e.g. a widget, a module) can be specially managed and used.
+ * In particular, if a message belongs to an extension whose class name is Xyz, then the message category
+ * can be specified in the format of 'Xyz.categoryName'. And the corresponding message file
+ * is assumed to be 'BasePath/messages/LanguageID/categoryName.php', where 'BasePath' refers to
+ * the directory that contains the extension class file. When using Yii::t() to translate an extension message,
+ * the category name should be set as 'Xyz.categoryName'.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @since 2.0
+ */
+class PhpMessageSource extends MessageSource
+{
+	const CACHE_KEY_PREFIX='Yii.CPhpMessageSource.';
+
+	/**
+	 * @var integer the time in seconds that the messages can remain valid in cache.
+	 * Defaults to 0, meaning the caching is disabled.
+	 */
+	public $cachingDuration=0;
+	/**
+	 * @var string the ID of the cache application component that is used to cache the messages.
+	 * Defaults to 'cache' which refers to the primary cache application component.
+	 * Set this property to false if you want to disable caching the messages.
+	 */
+	public $cacheID='cache';
+	/**
+	 * @var string the base path for all translated messages. Defaults to null, meaning
+	 * the "messages" subdirectory of the application directory (e.g. "protected/messages").
+	 */
+	public $basePath;
+	/**
+	 * @var array the message paths for extensions that do not have a base class to use as category prefix.
+	 * The format of the array should be:
+	 * <pre>
+	 * array(
+	 *     'ExtensionName' => 'ext.ExtensionName.messages',
+	 * )
+	 * </pre>
+	 * Where the key is the name of the extension and the value is the alias to the path
+	 * of the "messages" subdirectory of the extension.
+	 * When using Yii::t() to translate an extension message, the category name should be
+	 * set as 'ExtensionName.categoryName'.
+	 * Defaults to an empty array, meaning no extensions registered.
+	 * @since 1.1.13
+	 */
+	public $extensionPaths=array();
+
+	private $_files=array();
+
+	/**
+	 * Initializes the application component.
+	 * This method overrides the parent implementation by preprocessing
+	 * the user request data.
+	 */
+	public function init()
+	{
+		parent::init();
+		if($this->basePath===null)
+			$this->basePath=Yii::getPathOfAlias('application.messages');
+	}
+
+	/**
+	 * Determines the message file name based on the given category and language.
+	 * If the category name contains a dot, it will be split into the module class name and the category name.
+	 * In this case, the message file will be assumed to be located within the 'messages' subdirectory of
+	 * the directory containing the module class file.
+	 * Otherwise, the message file is assumed to be under the {@link basePath}.
+	 * @param string $category category name
+	 * @param string $language language ID
+	 * @return string the message file path
+	 */
+	protected function getMessageFile($category,$language)
+	{
+		if(!isset($this->_files[$category][$language]))
+		{
+			if(($pos=strpos($category,'.'))!==false)
+			{
+				$extensionClass=substr($category,0,$pos);
+				$extensionCategory=substr($category,$pos+1);
+				// First check if there's an extension registered for this class.
+				if(isset($this->extensionPaths[$extensionClass]))
+					$this->_files[$category][$language]=Yii::getPathOfAlias($this->extensionPaths[$extensionClass]).DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$extensionCategory.'.php';
+				else
+				{
+					// No extension registered, need to find it.
+					$class=new ReflectionClass($extensionClass);
+					$this->_files[$category][$language]=dirname($class->getFileName()).DIRECTORY_SEPARATOR.'messages'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$extensionCategory.'.php';
+				}
+			}
+			else
+				$this->_files[$category][$language]=$this->basePath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$category.'.php';
+		}
+		return $this->_files[$category][$language];
+	}
+
+	/**
+	 * Loads the message translation for the specified language and category.
+	 * @param string $category the message category
+	 * @param string $language the target language
+	 * @return array the loaded messages
+	 */
+	protected function loadMessages($category,$language)
+	{
+		$messageFile=$this->getMessageFile($category,$language);
+
+		if($this->cachingDuration>0 && $this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
+		{
+			$key=self::CACHE_KEY_PREFIX . $messageFile;
+			if(($data=$cache->get($key))!==false)
+				return unserialize($data);
+		}
+
+		if(is_file($messageFile))
+		{
+			$messages=include($messageFile);
+			if(!is_array($messages))
+				$messages=array();
+			if(isset($cache))
+			{
+				$dependency=new CFileCacheDependency($messageFile);
+				$cache->set($key,serialize($messages),$this->cachingDuration,$dependency);
+			}
+			return $messages;
+		}
+		else
+			return array();
+	}
+}
\ No newline at end of file
diff --git a/framework/logging/EmailTarget.php b/framework/logging/EmailTarget.php
index e02e4da..205cd06 100644
--- a/framework/logging/EmailTarget.php
+++ b/framework/logging/EmailTarget.php
@@ -50,7 +50,7 @@ class EmailTarget extends Target
 			$body .= $this->formatMessage($message);
 		}
 		$body = wordwrap($body, 70);
-		$subject = $this->subject === null ? \Yii::t('yii', 'Application Log') : $this->subject;
+		$subject = $this->subject === null ? \Yii::t('yii:Application Log') : $this->subject;
 		foreach ($this->emails as $email) {
 			$this->sendEmail($subject, $body, $email, $this->sentFrom, $this->headers);
 		}
diff --git a/framework/logging/ProfileTarget.php b/framework/logging/ProfileTarget.php
index 716e6b7..30a207c 100644
--- a/framework/logging/ProfileTarget.php
+++ b/framework/logging/ProfileTarget.php
@@ -61,7 +61,7 @@ class CProfileLogRoute extends CWebLogRoute
 		if ($value === 'summary' || $value === 'callstack')
 			$this->_report = $value;
 		else
-			throw new CException(Yii::t('yii', 'CProfileLogRoute.report "{report}" is invalid. Valid values include "summary" and "callstack".',
+			throw new CException(Yii::t('yii:CProfileLogRoute.report "{report}" is invalid. Valid values include "summary" and "callstack".',
 				array('{report}' => $value)));
 	}
 
@@ -108,7 +108,7 @@ class CProfileLogRoute extends CWebLogRoute
 					$results[$last[4]] = array($token, $delta, count($stack));
 				} else
 				{
-					throw new CException(Yii::t('yii', 'CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
+					throw new CException(Yii::t('yii:CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
 						array('{token}' => $token)));
 				}
 			}
@@ -151,7 +151,7 @@ class CProfileLogRoute extends CWebLogRoute
 					else
 						$results[$token] = array($token, 1, $delta, $delta, $delta);
 				} else
-					throw new CException(Yii::t('yii', 'CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
+					throw new CException(Yii::t('yii:CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
 						array('{token}' => $token)));
 			}
 		}
diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php
index 90e7939..a002ba5 100644
--- a/framework/validators/BooleanValidator.php
+++ b/framework/validators/BooleanValidator.php
@@ -54,7 +54,7 @@ class BooleanValidator extends Validator
 		}
 		if (!$this->strict && $value != $this->trueValue && $value != $this->falseValue
 				|| $this->strict && $value !== $this->trueValue && $value !== $this->falseValue) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be either {true} or {false}.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} must be either {true} or {false}.');
 			$this->addError($object, $attribute, $message, array(
 				'{true}' => $this->trueValue,
 				'{false}' => $this->falseValue,
@@ -70,7 +70,7 @@ class BooleanValidator extends Validator
 	 */
 	public function clientValidateAttribute($object, $attribute)
 	{
-		$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be either {true} or {false}.');
+		$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} must be either {true} or {false}.');
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
 			'{value}' => $object->$attribute,
diff --git a/framework/validators/CaptchaValidator.php b/framework/validators/CaptchaValidator.php
index 3da8ed6..e936f63 100644
--- a/framework/validators/CaptchaValidator.php
+++ b/framework/validators/CaptchaValidator.php
@@ -49,7 +49,7 @@ class CaptchaValidator extends Validator
 		}
 		$captcha = $this->getCaptchaAction();
 		if (!$captcha->validate($value, $this->caseSensitive)) {
-			$message = $this->message !== null ? $this->message : \Yii::t('yii', 'The verification code is incorrect.');
+			$message = $this->message !== null ? $this->message : \Yii::t('yii:The verification code is incorrect.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
@@ -85,7 +85,7 @@ class CaptchaValidator extends Validator
 	public function clientValidateAttribute($object, $attribute)
 	{
 		$captcha = $this->getCaptchaAction();
-		$message = $this->message !== null ? $this->message : \Yii::t('yii', 'The verification code is incorrect.');
+		$message = $this->message !== null ? $this->message : \Yii::t('yii:The verification code is incorrect.');
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
 			'{value}' => $object->$attribute,
diff --git a/framework/validators/CompareValidator.php b/framework/validators/CompareValidator.php
index 9345b73..141cb16 100644
--- a/framework/validators/CompareValidator.php
+++ b/framework/validators/CompareValidator.php
@@ -96,37 +96,37 @@ class CompareValidator extends Validator
 			case '=':
 			case '==':
 				if (($this->strict && $value !== $compareValue) || (!$this->strict && $value != $compareValue)) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must be repeated exactly.');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must be repeated exactly.');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel));
 				}
 				break;
 			case '!=':
 				if (($this->strict && $value === $compareValue) || (!$this->strict && $value == $compareValue)) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must not be equal to "{compareValue}".');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must not be equal to "{compareValue}".');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel, '{compareValue}' => $compareValue));
 				}
 				break;
 			case '>':
 				if ($value <= $compareValue) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must be greater than "{compareValue}".');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must be greater than "{compareValue}".');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel, '{compareValue}' => $compareValue));
 				}
 				break;
 			case '>=':
 				if ($value < $compareValue) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must be greater than or equal to "{compareValue}".');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must be greater than or equal to "{compareValue}".');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel, '{compareValue}' => $compareValue));
 				}
 				break;
 			case '<':
 				if ($value >= $compareValue) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must be less than "{compareValue}".');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must be less than "{compareValue}".');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel, '{compareValue}' => $compareValue));
 				}
 				break;
 			case '<=':
 				if ($value > $compareValue) {
-					$message = ($this->message !== null) ? $this->message : Yii::t('yii', '{attribute} must be less than or equal to "{compareValue}".');
+					$message = ($this->message !== null) ? $this->message : Yii::t('yii:{attribute} must be less than or equal to "{compareValue}".');
 					$this->addError($object, $attribute, $message, array('{compareAttribute}' => $compareLabel, '{compareValue}' => $compareValue));
 				}
 				break;
@@ -158,37 +158,37 @@ class CompareValidator extends Validator
 			case '=':
 			case '==':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must be repeated exactly.');
+					$message = Yii::t('yii:{attribute} must be repeated exactly.');
 				}
 				$condition = 'value!=' . $compareValue;
 				break;
 			case '!=':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must not be equal to "{compareValue}".');
+					$message = Yii::t('yii:{attribute} must not be equal to "{compareValue}".');
 				}
 				$condition = 'value==' . $compareValue;
 				break;
 			case '>':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must be greater than "{compareValue}".');
+					$message = Yii::t('yii:{attribute} must be greater than "{compareValue}".');
 				}
 				$condition = 'value<=' . $compareValue;
 				break;
 			case '>=':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must be greater than or equal to "{compareValue}".');
+					$message = Yii::t('yii:{attribute} must be greater than or equal to "{compareValue}".');
 				}
 				$condition = 'value<' . $compareValue;
 				break;
 			case '<':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must be less than "{compareValue}".');
+					$message = Yii::t('yii:{attribute} must be less than "{compareValue}".');
 				}
 				$condition = 'value>=' . $compareValue;
 				break;
 			case '<=':
 				if ($message === null) {
-					$message = Yii::t('yii', '{attribute} must be less than or equal to "{compareValue}".');
+					$message = Yii::t('yii:{attribute} must be less than or equal to "{compareValue}".');
 				}
 				$condition = 'value>' . $compareValue;
 				break;
diff --git a/framework/validators/DateValidator.php b/framework/validators/DateValidator.php
index f4fa866..af97a71 100644
--- a/framework/validators/DateValidator.php
+++ b/framework/validators/DateValidator.php
@@ -66,7 +66,7 @@ class DateValidator extends Validator
 		}
 
 		if (!$valid) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', 'The format of {attribute} is invalid.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:The format of {attribute} is invalid.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
diff --git a/framework/validators/EmailValidator.php b/framework/validators/EmailValidator.php
index 8fd8120..b78b2da 100644
--- a/framework/validators/EmailValidator.php
+++ b/framework/validators/EmailValidator.php
@@ -63,7 +63,7 @@ class EmailValidator extends Validator
 			return;
 		}
 		if (!$this->validateValue($value)) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is not a valid email address.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is not a valid email address.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
@@ -100,7 +100,7 @@ class EmailValidator extends Validator
 	 */
 	public function clientValidateAttribute($object, $attribute)
 	{
-		$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is not a valid email address.');
+		$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is not a valid email address.');
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
 			'{value}' => $object->$attribute,
diff --git a/framework/validators/ExistValidator.php b/framework/validators/ExistValidator.php
index be710bd..9d253c9 100644
--- a/framework/validators/ExistValidator.php
+++ b/framework/validators/ExistValidator.php
@@ -68,7 +68,7 @@ class ExistValidator extends Validator
 		$query = $className::find();
 		$query->where(array($column->name => $value));
 		if (!$query->exists()) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} "{value}" is invalid.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} "{value}" is invalid.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php
index 106b9a6..c558b76 100644
--- a/framework/validators/FileValidator.php
+++ b/framework/validators/FileValidator.php
@@ -115,7 +115,7 @@ class CFileValidator extends Validator
 				return $this->emptyAttribute($object, $attribute);
 			if (count($files) > $this->maxFiles)
 			{
-				$message = $this->tooMany !== null ? $this->tooMany : \Yii::t('yii', '{attribute} cannot accept more than {limit} files.');
+				$message = $this->tooMany !== null ? $this->tooMany : \Yii::t('yii:{attribute} cannot accept more than {limit} files.');
 				$this->addError($object, $attribute, $message, array('{attribute}' => $attribute, '{limit}' => $this->maxFiles));
 			} else
 				foreach ($files as $file)
@@ -145,20 +145,20 @@ class CFileValidator extends Validator
 			return $this->emptyAttribute($object, $attribute);
 		elseif ($error == UPLOAD_ERR_INI_SIZE || $error == UPLOAD_ERR_FORM_SIZE || $this->maxSize !== null && $file->getSize() > $this->maxSize)
 		{
-			$message = $this->tooLarge !== null ? $this->tooLarge : \Yii::t('yii', 'The file "{file}" is too large. Its size cannot exceed {limit} bytes.');
+			$message = $this->tooLarge !== null ? $this->tooLarge : \Yii::t('yii:The file "{file}" is too large. Its size cannot exceed {limit} bytes.');
 			$this->addError($object, $attribute, $message, array('{file}' => $file->getName(), '{limit}' => $this->getSizeLimit()));
 		} elseif ($error == UPLOAD_ERR_PARTIAL)
-			throw new CException(\Yii::t('yii', 'The file "{file}" was only partially uploaded.', array('{file}' => $file->getName())));
+			throw new CException(\Yii::t('yii:The file "{file}" was only partially uploaded.', array('{file}' => $file->getName())));
 		elseif ($error == UPLOAD_ERR_NO_TMP_DIR)
-			throw new CException(\Yii::t('yii', 'Missing the temporary folder to store the uploaded file "{file}".', array('{file}' => $file->getName())));
+			throw new CException(\Yii::t('yii:Missing the temporary folder to store the uploaded file "{file}".', array('{file}' => $file->getName())));
 		elseif ($error == UPLOAD_ERR_CANT_WRITE)
-			throw new CException(\Yii::t('yii', 'Failed to write the uploaded file "{file}" to disk.', array('{file}' => $file->getName())));
+			throw new CException(\Yii::t('yii:Failed to write the uploaded file "{file}" to disk.', array('{file}' => $file->getName())));
 		elseif (defined('UPLOAD_ERR_EXTENSION') && $error == UPLOAD_ERR_EXTENSION)  // available for PHP 5.2.0 or above
-			throw new CException(\Yii::t('yii', 'File upload was stopped by extension.'));
+			throw new CException(\Yii::t('yii:File upload was stopped by extension.'));
 
 		if ($this->minSize !== null && $file->getSize() < $this->minSize)
 		{
-			$message = $this->tooSmall !== null ? $this->tooSmall : \Yii::t('yii', 'The file "{file}" is too small. Its size cannot be smaller than {limit} bytes.');
+			$message = $this->tooSmall !== null ? $this->tooSmall : \Yii::t('yii:The file "{file}" is too small. Its size cannot be smaller than {limit} bytes.');
 			$this->addError($object, $attribute, $message, array('{file}' => $file->getName(), '{limit}' => $this->minSize));
 		}
 
@@ -170,7 +170,7 @@ class CFileValidator extends Validator
 				$types = $this->types;
 			if (!in_array(strtolower($file->getExtensionName()), $types))
 			{
-				$message = $this->wrongType !== null ? $this->wrongType : \Yii::t('yii', 'The file "{file}" cannot be uploaded. Only files with these extensions are allowed: {extensions}.');
+				$message = $this->wrongType !== null ? $this->wrongType : \Yii::t('yii:The file "{file}" cannot be uploaded. Only files with these extensions are allowed: {extensions}.');
 				$this->addError($object, $attribute, $message, array('{file}' => $file->getName(), '{extensions}' => implode(', ', $types)));
 			}
 		}
@@ -185,7 +185,7 @@ class CFileValidator extends Validator
 	{
 		if (!$this->allowEmpty)
 		{
-			$message = $this->message !== null ? $this->message : \Yii::t('yii', '{attribute} cannot be blank.');
+			$message = $this->message !== null ? $this->message : \Yii::t('yii:{attribute} cannot be blank.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php
index 4596fc1..d459fb8 100644
--- a/framework/validators/NumberValidator.php
+++ b/framework/validators/NumberValidator.php
@@ -73,21 +73,21 @@ class NumberValidator extends Validator
 		}
 		if ($this->integerOnly) {
 			if (!preg_match($this->integerPattern, "$value")) {
-				$message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} must be an integer.');
+				$message = $this->message !== null ? $this->message : Yii::t('yii:{attribute} must be an integer.');
 				$this->addError($object, $attribute, $message);
 			}
 		} else {
 			if (!preg_match($this->numberPattern, "$value")) {
-				$message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} must be a number.');
+				$message = $this->message !== null ? $this->message : Yii::t('yii:{attribute} must be a number.');
 				$this->addError($object, $attribute, $message);
 			}
 		}
 		if ($this->min !== null && $value < $this->min) {
-			$message = $this->tooSmall !== null ? $this->tooSmall : Yii::t('yii', '{attribute} is too small (minimum is {min}).');
+			$message = $this->tooSmall !== null ? $this->tooSmall : Yii::t('yii:{attribute} is too small (minimum is {min}).');
 			$this->addError($object, $attribute, $message, array('{min}' => $this->min));
 		}
 		if ($this->max !== null && $value > $this->max) {
-			$message = $this->tooBig !== null ? $this->tooBig : Yii::t('yii', '{attribute} is too big (maximum is {max}).');
+			$message = $this->tooBig !== null ? $this->tooBig : Yii::t('yii:{attribute} is too big (maximum is {max}).');
 			$this->addError($object, $attribute, $message, array('{max}' => $this->max));
 		}
 	}
@@ -103,8 +103,8 @@ class NumberValidator extends Validator
 		$label = $object->getAttributeLabel($attribute);
 
 		if (($message = $this->message) === null) {
-			$message = $this->integerOnly ? Yii::t('yii', '{attribute} must be an integer.')
-					: Yii::t('yii', '{attribute} must be a number.');
+			$message = $this->integerOnly ? Yii::t('yii:{attribute} must be an integer.')
+					: Yii::t('yii:{attribute} must be a number.');
 		}
 		$message = strtr($message, array(
 			'{attribute}' => $label,
@@ -118,7 +118,7 @@ if(!value.match($pattern)) {
 ";
 		if ($this->min !== null) {
 			if (($tooSmall = $this->tooSmall) === null) {
-				$tooSmall = Yii::t('yii', '{attribute} is too small (minimum is {min}).');
+				$tooSmall = Yii::t('yii:{attribute} is too small (minimum is {min}).');
 			}
 			$tooSmall = strtr($tooSmall, array(
 				'{attribute}' => $label,
@@ -133,7 +133,7 @@ if(value<{$this->min}) {
 		}
 		if ($this->max !== null) {
 			if (($tooBig = $this->tooBig) === null) {
-				$tooBig = Yii::t('yii', '{attribute} is too big (maximum is {max}).');
+				$tooBig = Yii::t('yii:{attribute} is too big (maximum is {max}).');
 			}
 			$tooBig = strtr($tooBig, array(
 				'{attribute}' => $label,
diff --git a/framework/validators/RangeValidator.php b/framework/validators/RangeValidator.php
index b2ff773..6abf81f 100644
--- a/framework/validators/RangeValidator.php
+++ b/framework/validators/RangeValidator.php
@@ -58,10 +58,10 @@ class RangeValidator extends Validator
 			throw new InvalidConfigException('The "range" property must be specified as an array.');
 		}
 		if (!$this->not && !in_array($value, $this->range, $this->strict)) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} should be in the list.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} should be in the list.');
 			$this->addError($object, $attribute, $message);
 		} elseif ($this->not && in_array($value, $this->range, $this->strict)) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} should NOT be in the list.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} should NOT be in the list.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
@@ -80,7 +80,7 @@ class RangeValidator extends Validator
 		}
 
 		if (($message = $this->message) === null) {
-			$message = $this->not ? \Yii::t('yii', '{attribute} should NOT be in the list.') : \Yii::t('yii', '{attribute} should be in the list.');
+			$message = $this->not ? \Yii::t('yii:{attribute} should NOT be in the list.') : \Yii::t('yii:{attribute} should be in the list.');
 		}
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
diff --git a/framework/validators/RegularExpressionValidator.php b/framework/validators/RegularExpressionValidator.php
index fbdb062..1e034f7 100644
--- a/framework/validators/RegularExpressionValidator.php
+++ b/framework/validators/RegularExpressionValidator.php
@@ -51,7 +51,7 @@ class RegularExpressionValidator extends Validator
 			throw new \yii\base\Exception('The "pattern" property must be specified with a valid regular expression.');
 		}
 		if ((!$this->not && !preg_match($this->pattern, $value)) || ($this->not && preg_match($this->pattern, $value))) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is invalid.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is invalid.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
@@ -69,7 +69,7 @@ class RegularExpressionValidator extends Validator
 			throw new \yii\base\Exception('The "pattern" property must be specified with a valid regular expression.');
 		}
 
-		$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is invalid.');
+		$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is invalid.');
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
 			'{value}' => $object->$attribute,
diff --git a/framework/validators/RequiredValidator.php b/framework/validators/RequiredValidator.php
index f0f4bfd..af03221 100644
--- a/framework/validators/RequiredValidator.php
+++ b/framework/validators/RequiredValidator.php
@@ -47,12 +47,12 @@ class RequiredValidator extends Validator
 		$value = $object->$attribute;
 		if ($this->requiredValue === null) {
 			if ($this->strict && $value === null || !$this->strict && $this->isEmpty($value, true)) {
-				$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} cannot be blank.');
+				$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} cannot be blank.');
 				$this->addError($object, $attribute, $message);
 			}
 		} else {
 			if (!$this->strict && $value != $this->requiredValue || $this->strict && $value !== $this->requiredValue) {
-				$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be "{requiredValue}".');
+				$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} must be "{requiredValue}".');
 				$this->addError($object, $attribute, $message, array(
 					'{requiredValue}' => $this->requiredValue,
 				));
@@ -71,7 +71,7 @@ class RequiredValidator extends Validator
 		$message = $this->message;
 		if ($this->requiredValue !== null) {
 			if ($message === null) {
-				$message = \Yii::t('yii', '{attribute} must be "{requiredValue}".');
+				$message = \Yii::t('yii:{attribute} must be "{requiredValue}".');
 			}
 			$message = strtr($message, array(
 				'{attribute}' => $object->getAttributeLabel($attribute),
@@ -85,7 +85,7 @@ if (value != " . json_encode($this->requiredValue) . ") {
 ";
 		} else {
 			if ($message === null) {
-				$message = \Yii::t('yii', '{attribute} cannot be blank.');
+				$message = \Yii::t('yii:{attribute} cannot be blank.');
 			}
 			$message = strtr($message, array(
 				'{attribute}' => $object->getAttributeLabel($attribute),
diff --git a/framework/validators/StringValidator.php b/framework/validators/StringValidator.php
index fe69a4d..4db29d3 100644
--- a/framework/validators/StringValidator.php
+++ b/framework/validators/StringValidator.php
@@ -76,7 +76,7 @@ class StringValidator extends Validator
 		}
 
 		if (!is_string($value)) {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be a string.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} must be a string.');
 			$this->addError($object, $attribute, $message);
 			return;
 		}
@@ -88,15 +88,15 @@ class StringValidator extends Validator
 		}
 
 		if ($this->min !== null && $length < $this->min) {
-			$message = ($this->tooShort !== null) ? $this->tooShort : \Yii::t('yii', '{attribute} is too short (minimum is {min} characters).');
+			$message = ($this->tooShort !== null) ? $this->tooShort : \Yii::t('yii:{attribute} is too short (minimum is {min} characters).');
 			$this->addError($object, $attribute, $message, array('{min}' => $this->min));
 		}
 		if ($this->max !== null && $length > $this->max) {
-			$message = ($this->tooLong !== null) ? $this->tooLong : \Yii::t('yii', '{attribute} is too long (maximum is {max} characters).');
+			$message = ($this->tooLong !== null) ? $this->tooLong : \Yii::t('yii:{attribute} is too long (maximum is {max} characters).');
 			$this->addError($object, $attribute, $message, array('{max}' => $this->max));
 		}
 		if ($this->is !== null && $length !== $this->is) {
-			$message = ($this->notEqual !== null) ? $this->notEqual : \Yii::t('yii', '{attribute} is of the wrong length (should be {length} characters).');
+			$message = ($this->notEqual !== null) ? $this->notEqual : \Yii::t('yii:{attribute} is of the wrong length (should be {length} characters).');
 			$this->addError($object, $attribute, $message, array('{length}' => $this->is));
 		}
 	}
@@ -113,7 +113,7 @@ class StringValidator extends Validator
 		$value = $object->$attribute;
 
 		if (($notEqual = $this->notEqual) === null) {
-			$notEqual = \Yii::t('yii', '{attribute} is of the wrong length (should be {length} characters).');
+			$notEqual = \Yii::t('yii:{attribute} is of the wrong length (should be {length} characters).');
 		}
 		$notEqual = strtr($notEqual, array(
 			'{attribute}' => $label,
@@ -122,7 +122,7 @@ class StringValidator extends Validator
 		));
 
 		if (($tooShort = $this->tooShort) === null) {
-			$tooShort = \Yii::t('yii', '{attribute} is too short (minimum is {min} characters).');
+			$tooShort = \Yii::t('yii:{attribute} is too short (minimum is {min} characters).');
 		}
 		$tooShort = strtr($tooShort, array(
 			'{attribute}' => $label,
@@ -131,7 +131,7 @@ class StringValidator extends Validator
 		));
 
 		if (($tooLong = $this->tooLong) === null) {
-			$tooLong = \Yii::t('yii', '{attribute} is too long (maximum is {max} characters).');
+			$tooLong = \Yii::t('yii:{attribute} is too long (maximum is {max} characters).');
 		}
 		$tooLong = strtr($tooLong, array(
 			'{attribute}' => $label,
diff --git a/framework/validators/UniqueValidator.php b/framework/validators/UniqueValidator.php
index 5d5e603..758d44f 100644
--- a/framework/validators/UniqueValidator.php
+++ b/framework/validators/UniqueValidator.php
@@ -86,7 +86,7 @@ class UniqueValidator extends Validator
 		}
 
 		if ($exists) {
-			$message = $this->message !== null ? $this->message : \Yii::t('yii', '{attribute} "{value}" has already been taken.');
+			$message = $this->message !== null ? $this->message : \Yii::t('yii:{attribute} "{value}" has already been taken.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
diff --git a/framework/validators/UrlValidator.php b/framework/validators/UrlValidator.php
index c6242a2..768e8d4 100644
--- a/framework/validators/UrlValidator.php
+++ b/framework/validators/UrlValidator.php
@@ -55,7 +55,7 @@ class UrlValidator extends Validator
 		if (($value = $this->validateValue($value)) !== false) {
 			$object->$attribute = $value;
 		} else {
-			$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is not a valid URL.');
+			$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is not a valid URL.');
 			$this->addError($object, $attribute, $message);
 		}
 	}
@@ -97,7 +97,7 @@ class UrlValidator extends Validator
 	 */
 	public function clientValidateAttribute($object, $attribute)
 	{
-		$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} is not a valid URL.');
+		$message = ($this->message !== null) ? $this->message : \Yii::t('yii:{attribute} is not a valid URL.');
 		$message = strtr($message, array(
 			'{attribute}' => $object->getAttributeLabel($attribute),
 			'{value}' => $object->$attribute,
diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php
index 2028a1c..bf27e6a 100644
--- a/framework/web/AssetManager.php
+++ b/framework/web/AssetManager.php
@@ -113,7 +113,7 @@ class CAssetManager extends CApplicationComponent
 		if(($basePath=realpath($value))!==false && is_dir($basePath) && is_writable($basePath))
 			$this->_basePath=$basePath;
 		else
-			throw new CException(Yii::t('yii','CAssetManager.basePath "{path}" is invalid. Please make sure the directory exists and is writable by the Web server process.',
+			throw new CException(Yii::t('yii:CAssetManager.basePath "{path}" is invalid. Please make sure the directory exists and is writable by the Web server process.',
 				array('{path}'=>$value)));
 	}
 
@@ -236,7 +236,7 @@ class CAssetManager extends CApplicationComponent
 				return $this->_published[$path]=$this->getBaseUrl().'/'.$dir;
 			}
 		}
-		throw new CException(Yii::t('yii','The asset "{asset}" to be published does not exist.',
+		throw new CException(Yii::t('yii:The asset "{asset}" to be published does not exist.',
 			array('{asset}'=>$path)));
 	}
 
diff --git a/framework/web/Controller.php b/framework/web/Controller.php
index 92722b5..e4c36c9 100644
--- a/framework/web/Controller.php
+++ b/framework/web/Controller.php
@@ -45,7 +45,7 @@ class Controller extends \yii\base\Controller
 	 */
 	public function invalidActionParams($action, $exception)
 	{
-		throw new HttpException(400, \Yii::t('yii', 'Your request is invalid.'));
+		throw new HttpException(400, \Yii::t('yii:Your request is invalid.'));
 	}
 
 	/**
diff --git a/framework/web/Request.php b/framework/web/Request.php
index 09e4864..9566974 100644
--- a/framework/web/Request.php
+++ b/framework/web/Request.php
@@ -823,7 +823,7 @@ class Request extends \yii\base\Request
 				$valid = false;
 			}
 			if (!$valid) {
-				throw new CHttpException(400, Yii::t('yii', 'The CSRF token could not be verified.'));
+				throw new CHttpException(400, Yii::t('yii:The CSRF token could not be verified.'));
 			}
 		}
 	}
diff --git a/framework/web/Session.php b/framework/web/Session.php
index 4544fc0..2b23e62 100644
--- a/framework/web/Session.php
+++ b/framework/web/Session.php
@@ -115,7 +115,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar
 		@session_start();
 		if(YII_DEBUG && session_id()=='')
 		{
-			$message=Yii::t('yii','Failed to start session.');
+			$message=Yii::t('yii:Failed to start session.');
 			if(function_exists('error_get_last'))
 			{
 				$error=error_get_last();
@@ -215,7 +215,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar
 		if(is_dir($value))
 			session_save_path($value);
 		else
-			throw new CException(Yii::t('yii','CHttpSession.savePath "{path}" is not a valid directory.',
+			throw new CException(Yii::t('yii:CHttpSession.savePath "{path}" is not a valid directory.',
 				array('{path}'=>$value)));
 	}
 
@@ -280,7 +280,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar
 			ini_set('session.use_only_cookies','1');
 		}
 		else
-			throw new CException(Yii::t('yii','CHttpSession.cookieMode can only be "none", "allow" or "only".'));
+			throw new CException(Yii::t('yii:CHttpSession.cookieMode can only be "none", "allow" or "only".'));
 	}
 
 	/**
@@ -304,7 +304,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar
 			ini_set('session.gc_divisor','100');
 		}
 		else
-			throw new CException(Yii::t('yii','CHttpSession.gcProbability "{value}" is invalid. It must be an integer between 0 and 100.',
+			throw new CException(Yii::t('yii:CHttpSession.gcProbability "{value}" is invalid. It must be an integer between 0 and 100.',
 				array('{value}'=>$value)));
 	}