Index: pro-violet-viettel/sourcecode/application/cache/smarty/compiled/6285c4ab471a1112d167cd99709b3140f773b082.file.test.php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/cache/smarty/compiled/6285c4ab471a1112d167cd99709b3140f773b082.file.test.php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/cache/smarty/compiled/6285c4ab471a1112d167cd99709b3140f773b082.file.test.php.php	(revision 345)
@@ -0,0 +1,22 @@
+<?php /* Smarty version Smarty-3.1.7, created on 2014-10-30 11:48:39
+         compiled from "application/modules/admin/views/test.php" */ ?>
+<?php /*%%SmartyHeaderCode:15508241715451c327effd33-55850599%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
+$_valid = $_smarty_tpl->decodeProperties(array (
+  'file_dependency' => 
+  array (
+    '6285c4ab471a1112d167cd99709b3140f773b082' => 
+    array (
+      0 => 'application/modules/admin/views/test.php',
+      1 => 1414644075,
+      2 => 'file',
+    ),
+  ),
+  'nocache_hash' => '15508241715451c327effd33-55850599',
+  'function' => 
+  array (
+  ),
+  'has_nocache_code' => false,
+  'version' => 'Smarty-3.1.7',
+  'unifunc' => 'content_5451c327f0d56',
+),false); /*/%%SmartyHeaderCode%%*/?>
+<?php if ($_valid && !is_callable('content_5451c327f0d56')) {function content_5451c327f0d56($_smarty_tpl) {?>456<?php }} ?>
Index: pro-violet-viettel/sourcecode/application/cache/smarty/compiled/896cc2d4903f7cb099be53ed4a004da1f1b4ab34.file.index.php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/cache/smarty/compiled/896cc2d4903f7cb099be53ed4a004da1f1b4ab34.file.index.php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/cache/smarty/compiled/896cc2d4903f7cb099be53ed4a004da1f1b4ab34.file.index.php.php	(revision 345)
@@ -0,0 +1,22 @@
+<?php /* Smarty version Smarty-3.1.7, created on 2014-10-30 11:45:20
+         compiled from "application/views/index.php" */ ?>
+<?php /*%%SmartyHeaderCode:8932258835451c11dec4242-84494553%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
+$_valid = $_smarty_tpl->decodeProperties(array (
+  'file_dependency' => 
+  array (
+    '896cc2d4903f7cb099be53ed4a004da1f1b4ab34' => 
+    array (
+      0 => 'application/views/index.php',
+      1 => 1414644316,
+      2 => 'file',
+    ),
+  ),
+  'nocache_hash' => '8932258835451c11dec4242-84494553',
+  'function' => 
+  array (
+  ),
+  'version' => 'Smarty-3.1.7',
+  'unifunc' => 'content_5451c11ded4c1',
+  'has_nocache_code' => false,
+),false); /*/%%SmartyHeaderCode%%*/?>
+<?php if ($_valid && !is_callable('content_5451c11ded4c1')) {function content_5451c11ded4c1($_smarty_tpl) {?>123456<?php }} ?>
Index: pro-violet-viettel/sourcecode/application/cache/smarty/compiled/8b2d10c353cfdb015a96e339ea08ab72495dbf35.file.listview.php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/cache/smarty/compiled/8b2d10c353cfdb015a96e339ea08ab72495dbf35.file.listview.php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/cache/smarty/compiled/8b2d10c353cfdb015a96e339ea08ab72495dbf35.file.listview.php.php	(revision 345)
@@ -0,0 +1,315 @@
+<?php /* Smarty version Smarty-3.1.7, created on 2014-10-30 15:14:35
+         compiled from "application/modules/admin/views/collaborator/listview.php" */ ?>
+<?php /*%%SmartyHeaderCode:691235965451c611936948-25061103%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
+$_valid = $_smarty_tpl->decodeProperties(array (
+  'file_dependency' => 
+  array (
+    '8b2d10c353cfdb015a96e339ea08ab72495dbf35' => 
+    array (
+      0 => 'application/modules/admin/views/collaborator/listview.php',
+      1 => 1414656631,
+      2 => 'file',
+    ),
+  ),
+  'nocache_hash' => '691235965451c611936948-25061103',
+  'function' => 
+  array (
+  ),
+  'version' => 'Smarty-3.1.7',
+  'unifunc' => 'content_5451c61194a0f',
+  'variables' => 
+  array (
+    'itemsoptions' => 0,
+    'option' => 0,
+    'perpage' => 0,
+    'keyword' => 0,
+    'collaborators' => 0,
+    'collaborator' => 0,
+    'paging' => 0,
+  ),
+  'has_nocache_code' => false,
+),false); /*/%%SmartyHeaderCode%%*/?>
+<?php if ($_valid && !is_callable('content_5451c61194a0f')) {function content_5451c61194a0f($_smarty_tpl) {?><div id="breadcrumbs" class="breadcrumbs">
+    <script type="text/javascript">
+        try{ace.settings.check('breadcrumbs' , 'fixed')}catch(e){}
+    </script>
+
+    <ul class="breadcrumb">
+        <li>
+            <i class="icon-home home-icon"></i>
+            <a href="#">Trang chá»§</a>
+        </li>
+
+        <li>
+            <a href="#">Quáº£n lÃœ tÃ i khoáº£n</a>
+        </li>
+        <li>
+            <a href="#">NgÆ°á»i dÃ¹ng</a>
+        </li>
+        <li class="active">Cá»ng tÃ¡c viÃªn</li>
+    </ul><!-- .breadcrumb -->
+
+    <div id="nav-search" class="nav-search">
+        <form class="form-search">
+            <span class="input-icon">
+                <input type="text" autocomplete="off" id="nav-search-input" class="nav-search-input" placeholder="TÃ¬m kiáº¿m ...">
+                <i class="icon-search nav-search-icon"></i>
+            </span>
+        </form>
+    </div><!-- #nav-search -->
+</div>
+<div class="page-content">
+    <div class="page-header">
+        <h1>
+            Cá»ng tÃ¡c viÃªn
+            <small>
+                <i class="icon-double-angle-right"></i>
+                thá»ng kÃª tÃ i khoáº£n
+            </small>
+        </h1>
+    </div><!-- /.page-header -->
+
+    <div class="row">
+        <div class="col-xs-12">
+            <!-- PAGE CONTENT BEGINS -->
+            <div style="padding-bottom:4px" class="table-header">
+                Thá»ng kÃª tÃ i khoáº£n
+
+                <button href="#addUser" data-toggle="modal" class="btn btn-success pull-right">
+                    <i class="icon-plus"></i>
+                    ThÃªm cá»ng tÃ¡c viÃªn
+                </button>
+
+            </div>
+
+            <div class="table-responsive">
+                <div role="grid" class="dataTables_wrapper" id="sample-table-2_wrapper">
+                    <form onsubmit="return false;" id="collaborator" >
+                    <div class="row">
+                        <div class="col-sm-6">
+                            <div id="sample-table-2_length" class="dataTables_length"><label>Hiá»n thá» 
+                                    <select onchange="filter();" name="items" size="1" aria-controls="sample-table-2">                                      
+                                        <?php  $_smarty_tpl->tpl_vars['option'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['option']->_loop = false;
+ $_from = $_smarty_tpl->tpl_vars['itemsoptions']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
+foreach ($_from as $_smarty_tpl->tpl_vars['option']->key => $_smarty_tpl->tpl_vars['option']->value){
+$_smarty_tpl->tpl_vars['option']->_loop = true;
+?>
+                                        <option <?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['option']->value;?>
+<?php $_tmp1=ob_get_clean();?><?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['perpage']->value;?>
+<?php $_tmp2=ob_get_clean();?><?php if (($_tmp1==$_tmp2)){?> selected<?php }?> value="<?php echo $_smarty_tpl->tpl_vars['option']->value;?>
+"><?php echo $_smarty_tpl->tpl_vars['option']->value;?>
+</option>
+                                        <?php } ?>
+                                    </select> báº£n ghi</label>
+                            
+                            </div>
+                        </div>
+                        
+                        <div class="col-sm-6">
+                            <div class="dataTables_filter" id="sample-table-2_filter">
+                                <label>TÃ¬m kiáº¿m: 
+                                    <input type="text" name="keyword" id="keyword" value='<?php echo $_smarty_tpl->tpl_vars['keyword']->value;?>
+' aria-controls="sample-table-2"></label>
+                            </div>
+                        </div>
+                    </div>
+                    </form>
+                    <table class="table table-striped table-bordered table-hover dataTable" id="sample-table-2" aria-describedby="sample-table-2_info">
+                        <thead>
+                            <tr role="row"><th class="center sorting_disabled" role="columnheader" rowspan="1" colspan="1" style="width: 44px;" aria-label="">
+                                    <label>
+                                        <input type="checkbox" class="ace">
+                                        <span class="lbl"></span>
+                                    </label>
+                                </th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 176px;" aria-label="Sá» Äiá»n thoáº¡i: activate to sort column ascending">Sá» Äiá»n thoáº¡i</th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 183px;" aria-label="Há» tÃªn: activate to sort column ascending">Há» tÃªn</th><th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 122px;" aria-label="Tiá»n: activate to sort column ascending">Tiá»n</th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 209px;" aria-label="
+
+                                                                                                                                                                                                        NgÃ y ÄÄng kÃœ
+                                                                                                                                                                                                        : activate to sort column ascending">
+                                    <i class="icon-time bigger-110 hidden-480"></i>
+                                    NgÃ y ÄÄng kÃœ
+                                </th><th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 158px;" aria-label="Tráº¡ng thÃ¡i: activate to sort column ascending">Tráº¡ng thÃ¡i</th><th class="sorting_disabled" role="columnheader" rowspan="1" colspan="1" style="width: 133px;" aria-label=""></th></tr>
+                        </thead>
+
+
+                        <tbody role="alert" aria-live="polite" aria-relevant="all">
+                            <?php  $_smarty_tpl->tpl_vars['collaborator'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['collaborator']->_loop = false;
+ $_from = $_smarty_tpl->tpl_vars['collaborators']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
+foreach ($_from as $_smarty_tpl->tpl_vars['collaborator']->key => $_smarty_tpl->tpl_vars['collaborator']->value){
+$_smarty_tpl->tpl_vars['collaborator']->_loop = true;
+?>
+                            <tr class="odd">
+                                <td class="center  sorting_1">
+                                    <label>
+                                        <input type="checkbox" class="ace">
+                                        <span class="lbl"></span>
+                                    </label>
+                                </td>
+
+                                <td class=" ">
+                                    <a href="#"><?php echo $_smarty_tpl->tpl_vars['collaborator']->value['cellphone'];?>
+</a>
+                                </td>
+                                <td class=" "><?php echo $_smarty_tpl->tpl_vars['collaborator']->value['full_name'];?>
+</td>
+                                <td class="hidden-480 ">3,330 VND</td>
+                                <td class=" "><?php echo $_smarty_tpl->tpl_vars['collaborator']->value['created_time'];?>
+</td>
+
+                                <td class="hidden-480 ">
+                                    <?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['collaborator']->value['activated'];?>
+<?php $_tmp3=ob_get_clean();?><?php if (($_tmp3)==1){?>
+                                    <span class="label label-sm label-success">KÃ­ch hoáº¡t</span>
+                                    <?php }?>
+                                    <?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['collaborator']->value['activated'];?>
+<?php $_tmp4=ob_get_clean();?><?php if (($_tmp4)==0){?>
+                                    <span class="label label-sm label-default">ChÆ°a kÃ­ch hoáº¡t</span>
+                                    <?php }?>
+                                </td>
+
+                                <td class=" ">
+                                    <div class="visible-md visible-lg hidden-sm hidden-xs action-buttons">
+                                        <a href="#" class="blue">
+                                            <i class="icon-zoom-in bigger-130"></i>
+                                        </a>
+
+                                        <a href="#" class="green">
+                                            <i class="icon-pencil bigger-130"></i>
+                                        </a>
+
+                                        <a href="#" class="red">
+                                            <i class="icon-trash bigger-130"></i>
+                                        </a>
+                                    </div>
+
+                                    <div class="visible-xs visible-sm hidden-md hidden-lg">
+                                        <div class="inline position-relative">
+                                            <button data-toggle="dropdown" class="btn btn-minier btn-yellow dropdown-toggle">
+                                                <i class="icon-caret-down icon-only bigger-120"></i>
+                                            </button>
+
+                                            <ul class="dropdown-menu dropdown-only-icon dropdown-yellow pull-right dropdown-caret dropdown-close">
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-info" href="#" data-original-title="View">
+                                                        <span class="blue">
+                                                            <i class="icon-zoom-in bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-success" href="#" data-original-title="Edit">
+                                                        <span class="green">
+                                                            <i class="icon-edit bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-error" href="#" data-original-title="Delete">
+                                                        <span class="red">
+                                                            <i class="icon-trash bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+                                            </ul>
+                                        </div>
+                                    </div>
+                                </td>
+                            </tr>
+                            <?php } ?>
+
+
+                            
+                        
+                        
+                        
+                        
+                        </tbody></table><div class="row"><div class="col-sm-6"><div class="dataTables_info" id="sample-table-2_info">Hiá»n thá» 1 Äáº¿n 2 cá»§a 2 báº£n ghi</div></div>
+                            <div class="col-sm-6">
+                                <div class="dataTables_paginate paging_bootstrap">
+                                    <ul class="pagination">
+                                        <?php echo $_smarty_tpl->tpl_vars['paging']->value;?>
+
+                                    </ul>
+                                </div>
+                            </div>
+                        </div>
+                    
+                </div>
+            </div>
+
+            <div id="addUser" class="modal fade in" tabindex="-1">
+                <div class="modal-dialog">
+                    <div class="modal-content">
+                        <div class="modal-header no-padding">
+                            <div class="table-header">
+                                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
+                                    <span class="white">Ã</span>
+                                </button>
+                                ThÃªm cá»ng tÃ¡c viÃªn
+                            </div>
+                        </div>
+
+                        <div class="modal-body">
+                            <form class="form-horizontal" role="form">
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label no-padding-right" for="form-field-1"> TÃ i khoáº£n </label>
+
+                                    <div class="col-sm-9">
+                                        <span class="input-icon">
+                                            <input type="text" id="form-field-1" placeholder="TÃ i khoáº£n">
+                                            <i class="icon-user blue"></i>
+                                        </span>
+                                    </div>
+                                    <div class="help-block"> </div>
+                                </div>
+
+                                <div class="space-4"></div>
+
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label no-padding-right" for="form-field-2"> Máº­t kháº©u </label>
+
+                                    <div class="col-sm-9">
+                                        <span class="input-icon">
+                                            <input type="password" id="form-field-2" placeholder="Máº­t kháº©u">
+                                            <i class="icon-lock blue"></i>
+                                        </span>
+                                    </div>
+                                    <div class="help-block"> </div>
+                                </div>
+
+                                <div class="space-4"></div>
+
+                                <div class="clearfix form-actions">
+                                    <div class="col-md-offset-3 col-md-9">
+                                        <button class="btn btn-info" type="button">
+                                            <i class="icon-ok bigger-110"></i>
+                                            HoÃ n táº¥t
+                                        </button>
+
+                                        &nbsp; &nbsp; &nbsp;
+                                        <button class="btn" type="reset">
+                                            <i class="icon-undo bigger-110"></i>
+                                            XÃ³a háº¿t
+                                        </button>
+                                    </div>
+                                </div>
+
+                            </form></div>
+
+                    </div>
+                </div><!-- /.modal-content -->
+            </div><!-- /.modal-dialog -->
+        </div>
+
+        <!-- PAGE CONTENT ENDS -->
+    </div><!-- /.col -->
+</div>
+<script type="text/javascript">
+            window.onload = function ()
+{
+init_page();
+}
+
+
+</script><?php }} ?>
Index: pro-violet-viettel/sourcecode/application/cache/smarty/compiled/bb6499b8e938f92a3695fff1afe57edea4b9efb7.file.index.php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/cache/smarty/compiled/bb6499b8e938f92a3695fff1afe57edea4b9efb7.file.index.php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/cache/smarty/compiled/bb6499b8e938f92a3695fff1afe57edea4b9efb7.file.index.php.php	(revision 345)
@@ -0,0 +1,226 @@
+<?php /* Smarty version Smarty-3.1.7, created on 2014-10-30 11:39:11
+         compiled from "index.php" */ ?>
+<?php /*%%SmartyHeaderCode:716593695451c0ef901c10-29007368%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
+$_valid = $_smarty_tpl->decodeProperties(array (
+  'file_dependency' => 
+  array (
+    'bb6499b8e938f92a3695fff1afe57edea4b9efb7' => 
+    array (
+      0 => 'index.php',
+      1 => 1414636706,
+      2 => 'file',
+    ),
+  ),
+  'nocache_hash' => '716593695451c0ef901c10-29007368',
+  'function' => 
+  array (
+  ),
+  'has_nocache_code' => false,
+  'version' => 'Smarty-3.1.7',
+  'unifunc' => 'content_5451c0ef96af6',
+),false); /*/%%SmartyHeaderCode%%*/?>
+<?php if ($_valid && !is_callable('content_5451c0ef96af6')) {function content_5451c0ef96af6($_smarty_tpl) {?><<?php ?>?php
+date_default_timezone_set("Asia/Ho_Chi_Minh");
+/*
+ *---------------------------------------------------------------
+ * APPLICATION ENVIRONMENT
+ *---------------------------------------------------------------
+ *
+ * You can load different configurations depending on your
+ * current environment. Setting the environment also influences
+ * things like logging and error reporting.
+ *
+ * This can be set to anything, but default usage is:
+ *
+ *     development
+ *     testing
+ *     production
+ *
+ * NOTE: If you change these, also change the error_reporting() code below
+ *
+ */
+	define('ENVIRONMENT', 'development');
+/*
+ *---------------------------------------------------------------
+ * ERROR REPORTING
+ *---------------------------------------------------------------
+ *
+ * Different environments will require different levels of error reporting.
+ * By default development will show errors but testing and live will hide them.
+ */
+
+if (defined('ENVIRONMENT'))
+{
+	switch (ENVIRONMENT)
+	{
+		case 'development':
+			error_reporting(E_ALL);
+		break;
+	
+		case 'testing':
+		case 'production':
+			error_reporting(0);
+		break;
+
+		default:
+			exit('The application environment is not set correctly.');
+	}
+}
+
+/*
+ *---------------------------------------------------------------
+ * SYSTEM FOLDER NAME
+ *---------------------------------------------------------------
+ *
+ * This variable must contain the name of your "system" folder.
+ * Include the path if the folder is not in the same  directory
+ * as this file.
+ *
+ */
+	$system_path = 'system';
+
+/*
+ *---------------------------------------------------------------
+ * APPLICATION FOLDER NAME
+ *---------------------------------------------------------------
+ *
+ * If you want this front controller to use a different "application"
+ * folder then the default one you can set its name here. The folder
+ * can also be renamed or relocated anywhere on your server.  If
+ * you do, use a full server path. For more info please see the user guide:
+ * http://codeigniter.com/user_guide/general/managing_apps.html
+ *
+ * NO TRAILING SLASH!
+ *
+ */
+	$application_folder = 'application';
+
+/*
+ * --------------------------------------------------------------------
+ * DEFAULT CONTROLLER
+ * --------------------------------------------------------------------
+ *
+ * Normally you will set your default controller in the routes.php file.
+ * You can, however, force a custom routing by hard-coding a
+ * specific controller class/function here.  For most applications, you
+ * WILL NOT set your routing here, but it's an option for those
+ * special instances where you might want to override the standard
+ * routing in a specific front controller that shares a common CI installation.
+ *
+ * IMPORTANT:  If you set the routing here, NO OTHER controller will be
+ * callable. In essence, this preference limits your application to ONE
+ * specific controller.  Leave the function name blank if you need
+ * to call functions dynamically via the URI.
+ *
+ * Un-comment the $routing array below to use this feature
+ *
+ */
+	// The directory name, relative to the "controllers" folder.  Leave blank
+	// if your controller is not in a sub-folder within the "controllers" folder
+	// $routing['directory'] = '';
+
+	// The controller class file name.  Example:  Mycontroller
+	// $routing['controller'] = '';
+
+	// The controller function you wish to be called.
+	// $routing['function']	= '';
+
+
+/*
+ * -------------------------------------------------------------------
+ *  CUSTOM CONFIG VALUES
+ * -------------------------------------------------------------------
+ *
+ * The $assign_to_config array below will be passed dynamically to the
+ * config class when initialized. This allows you to set custom config
+ * items or override any default config values found in the config.php file.
+ * This can be handy as it permits you to share one application between
+ * multiple front controller files, with each file containing different
+ * config values.
+ *
+ * Un-comment the $assign_to_config array below to use this feature
+ *
+ */
+	// $assign_to_config['name_of_config_item'] = 'value of config item';
+
+
+
+// --------------------------------------------------------------------
+// END OF USER CONFIGURABLE SETTINGS.  DO NOT EDIT BELOW THIS LINE
+// --------------------------------------------------------------------
+
+/*
+ * ---------------------------------------------------------------
+ *  Resolve the system path for increased reliability
+ * ---------------------------------------------------------------
+ */
+
+	// Set the current directory correctly for CLI requests
+	if (defined('STDIN'))
+	{
+		chdir(dirname(__FILE__));
+	}
+
+	if (realpath($system_path) !== FALSE)
+	{
+		$system_path = realpath($system_path).'/';
+	}
+
+	// ensure there's a trailing slash
+	$system_path = rtrim($system_path, '/').'/';
+
+	// Is the system path correct?
+	if ( ! is_dir($system_path))
+	{
+		exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".pathinfo(__FILE__, PATHINFO_BASENAME));
+	}
+
+/*
+ * -------------------------------------------------------------------
+ *  Now that we know the path, set the main path constants
+ * -------------------------------------------------------------------
+ */
+	// The name of THIS file
+	define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
+
+	// The PHP file extension
+	// this global constant is deprecated.
+	define('EXT', '.php');
+
+	// Path to the system folder
+	define('BASEPATH', str_replace("\\", "/", $system_path));
+
+	// Path to the front controller (this file)
+	define('FCPATH', str_replace(SELF, '', __FILE__));
+
+	// Name of the "system folder"
+	define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/'));
+
+
+	// The path to the "application" folder
+	if (is_dir($application_folder))
+	{
+		define('APPPATH', $application_folder.'/');
+	}
+	else
+	{
+		if ( ! is_dir(BASEPATH.$application_folder.'/'))
+		{
+			exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF);
+		}
+
+		define('APPPATH', BASEPATH.$application_folder.'/');
+	}
+
+/*
+ * --------------------------------------------------------------------
+ * LOAD THE BOOTSTRAP FILE
+ * --------------------------------------------------------------------
+ *
+ * And away we go...
+ *
+ */
+require_once BASEPATH.'core/CodeIgniter.php';
+
+/* End of file index.php */
+/* Location: ./index.php */<?php }} ?>
Index: pro-violet-viettel/sourcecode/application/cache/smarty/compiled/cc5f0c5b0d9f85a3d795e56a90f467a99ad4477a.file.header.php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/cache/smarty/compiled/cc5f0c5b0d9f85a3d795e56a90f467a99ad4477a.file.header.php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/cache/smarty/compiled/cc5f0c5b0d9f85a3d795e56a90f467a99ad4477a.file.header.php.php	(revision 345)
@@ -0,0 +1,22 @@
+<?php /* Smarty version Smarty-3.1.7, created on 2014-10-30 11:50:33
+         compiled from "application/views/layout/admin/header.php" */ ?>
+<?php /*%%SmartyHeaderCode:1573574515451c399e77a91-84289825%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
+$_valid = $_smarty_tpl->decodeProperties(array (
+  'file_dependency' => 
+  array (
+    'cc5f0c5b0d9f85a3d795e56a90f467a99ad4477a' => 
+    array (
+      0 => 'application/views/layout/admin/header.php',
+      1 => 1414644632,
+      2 => 'file',
+    ),
+  ),
+  'nocache_hash' => '1573574515451c399e77a91-84289825',
+  'function' => 
+  array (
+  ),
+  'has_nocache_code' => false,
+  'version' => 'Smarty-3.1.7',
+  'unifunc' => 'content_5451c399e7df5',
+),false); /*/%%SmartyHeaderCode%%*/?>
+<?php if ($_valid && !is_callable('content_5451c399e7df5')) {function content_5451c399e7df5($_smarty_tpl) {?>369<?php }} ?>
Index: pro-violet-viettel/sourcecode/application/config/autoload.php
===================================================================
--- pro-violet-viettel/sourcecode/application/config/autoload.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/config/autoload.php	(revision 345)
@@ -53,5 +53,5 @@
 */
 
-$autoload['libraries'] = array('curl', 'xml','database', 'vservices');
+$autoload['libraries'] = array('parser','doctrine','curl', 'xml','database', 'vservices','session');
 
 
Index: pro-violet-viettel/sourcecode/application/config/database.php
===================================================================
--- pro-violet-viettel/sourcecode/application/config/database.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/config/database.php	(revision 345)
@@ -51,5 +51,5 @@
 $db['default']['hostname'] = 'mysql:host=127.0.0.1';
 $db['default']['username'] = 'root';
-$db['default']['password'] = '123456';
+$db['default']['password'] = 'Quyenhue@123';
 $db['default']['database'] = 'violet-viettel';
 $db['default']['dbdriver'] = 'pdo';
Index: pro-violet-viettel/sourcecode/application/config/plentyparser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/config/plentyparser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/config/plentyparser.php	(revision 345)
@@ -0,0 +1,71 @@
+<?php
+
+/**
+* @name Plenty Parser
+* @subpackage Config
+* @copyright 2011
+* @author Dwayne Charrington
+* @license http://philsturgeon.co.uk/code/dbad-license
+* @version 1.0
+*/
+
+// Default driver to render views with
+$config['parser.driver'] = "smarty";
+
+// Is the theming system enabled or disabled
+$config['parser.theme.enabled'] = false;
+
+// Where are themes located?
+$config['parser.theme.locations'] = array(
+    APPPATH . "themes",
+    FCPATH . "themes"
+);
+
+// Default theme to use
+$config['parser.theme.default'] = "";
+
+
+
+// Twig template extension (default)
+$config['parser.twig.extension'] = ".twig";
+
+// Default template location
+$config['parser.twig.location'] = APPPATH . "";
+
+// Twig template caching location
+$config['parser.twig.cache_location'] = APPPATH . "cache/twig/";
+
+// Debug mode turned on or off for Twig?
+$config['parser.twig.debug'] = false;
+
+
+
+// Smarty template extension (default)
+$config['parser.smarty.extension'] = ".php";
+
+// Left delimiter
+$config['parser.smarty.left.delim'] = "{";
+
+// Right delimiter
+$config['parser.smarty.right.delim'] = "}";
+
+// Default location for finding Smarty templates
+$config['parser.smarty.location'] = APPPATH . "";
+
+// Where compiled Smarty templates will reside
+$config['parser.smarty.compile_dir'] = APPPATH . "cache/smarty/compiled/";
+
+// Where Smarty caching happens
+$config['parser.smarty.cache_dir'] = APPPATH . "cache/smarty/";
+
+// Smarty configs directory
+$config['parser.smarty.config_dir'] = APPPATH."third_party/Smarty/configs/";
+
+// Smarty caching enabled by default unless explicitly set to 0
+$config['parser.smarty.cache_status'] = 1;
+
+// Cache lifetime. Default value is 3600 seconds (1 hour) Smarty's default value
+$config['parser.smarty.cache_lifetime'] = 3600;
+
+// Debug mode turned on or off?
+$config['parser.smarty.debug'] = false;
Index: pro-violet-viettel/sourcecode/application/config/routes.php
===================================================================
--- pro-violet-viettel/sourcecode/application/config/routes.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/config/routes.php	(revision 345)
@@ -44,4 +44,8 @@
 $route['violetservice/soanbai/mo'] = 'services/viettel/mo';
 $route['admin'] = 'admin/home';
+$route['admin/cong_tac_vien'] = 'admin/collaborator';
+$route['admin/cong_tac_vien/trang'] = 'admin/collaborator/getCollaborators/1';
+$route['admin/cong_tac_vien/trang/:any'] = 'admin/collaborator/getCollaborators/$1';
+$route['admin/cong_tac_vien/test'] = 'admin/collaborator/test';
 /* End of file routes.php */
 /* Location: ./application/config/routes.php */
Index: pro-violet-viettel/sourcecode/application/doctrine.php
===================================================================
--- pro-violet-viettel/sourcecode/application/doctrine.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/doctrine.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+// trailing slash is important!
+define('APPPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
+define('BASEPATH', APPPATH);
+define('ENVIRONMENT', 'production');
+
+require APPPATH.'libraries/Doctrine.php';
+
+$doctrine = new Doctrine();
+ 
+$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
+    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($doctrine->em->getConnection()),
+    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($doctrine->em)
+));
+
+$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen)', Doctrine\ORM\Version::VERSION);
+$cli->setCatchExceptions(true);
+$cli->setHelperSet($helperSet);
+$cli->addCommands(array(
+    // DBAL Commands
+    new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
+    new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
+ 
+    // ORM Commands
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
+ 
+));
+$cli->run();
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+
+class Doctrine
+{
+    // the Doctrine entity manager
+    public $em = null;
+
+    public function __construct()
+    {
+        // include our CodeIgniter application's database configuration
+        require_once APPPATH.'config/database.php';
+        
+        // include Doctrine's fancy ClassLoader class
+        require_once APPPATH.'libraries/Doctrine/Common/ClassLoader.php';
+
+        // load the Doctrine classes
+        $doctrineClassLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPPATH.'libraries');
+        $doctrineClassLoader->register();
+        
+        // load Symfony2 helpers
+        // Don't be alarmed, this is necessary for YAML mapping files
+        $symfonyClassLoader = new \Doctrine\Common\ClassLoader('Symfony', APPPATH.'libraries/Doctrine');
+        $symfonyClassLoader->register();
+
+        // load the entities
+        $entityClassLoader = new \Doctrine\Common\ClassLoader('Entities', APPPATH.'models');
+        $entityClassLoader->register();
+
+        // load the proxy entities
+        $proxyClassLoader = new \Doctrine\Common\ClassLoader('Proxies', APPPATH.'models');
+        $proxyClassLoader->register();
+
+        // set up the configuration 
+        $config = new \Doctrine\ORM\Configuration;
+    
+        if(ENVIRONMENT == 'development')
+            // set up simple array caching for development mode
+            $cache = new \Doctrine\Common\Cache\ArrayCache;
+        else
+            // set up caching with APC for production mode
+            $cache = new \Doctrine\Common\Cache\ApcCache;
+        $config->setMetadataCacheImpl($cache);
+        $config->setQueryCacheImpl($cache);
+
+        // set up proxy configuration
+        $config->setProxyDir(APPPATH.'models/Proxies');
+        $config->setProxyNamespace('Proxies');
+        
+        // auto-generate proxy classes if we are in development mode
+        $config->setAutoGenerateProxyClasses(ENVIRONMENT == 'development');
+
+        // set up annotation driver
+        $yamlDriver = new \Doctrine\ORM\Mapping\Driver\YamlDriver(APPPATH.'models/Mappings');
+        $config->setMetadataDriverImpl($yamlDriver);
+
+        // Database connection information
+        $connectionOptions = array(
+            'driver' => 'pdo_mysql',
+            'user' => 'root',
+            'password' => 'Quyenhue@123',
+            'host' => 'localhost',
+            'dbname' => 'violet-viettel',
+			'charset' => 'utf8',
+            'driverOptions' => array(
+                        1002=>'SET NAMES utf8'
+                )
+        );
+
+        
+        // create the EntityManager
+        $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
+        
+        // store it as a member, for use in our CodeIgniter controllers.
+        $this->em = $em;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation.php	(revision 345)
@@ -0,0 +1,75 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Annotations class
+ *
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Annotation
+{
+    /**
+     * Value property. Common among all derived classes.
+     *
+     * @var string
+     */
+    public $value;
+
+    /**
+     * Constructor
+     *
+     * @param array $data Key-value for properties to be defined in this class
+     */
+    public final function __construct(array $data)
+    {
+        foreach ($data as $key => $value) {
+            $this->$key = $value;
+        }
+    }
+
+    /**
+     * Error handler for unknown property accessor in Annotation class.
+     *
+     * @param string $name Unknown property name
+     */
+    public function __get($name)
+    {
+        throw new \BadMethodCallException(
+            sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
+        );
+    }
+
+    /**
+     * Error handler for unknown property mutator in Annotation class.
+     *
+     * @param string $name Unkown property name
+     * @param mixed $value Property value
+     */
+    public function __set($name, $value)
+    {
+        throw new \BadMethodCallException(
+            sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attribute.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attribute.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attribute.php	(revision 345)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the attribute type during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Attribute
+{
+    /**
+     * @var string
+     */
+    public $name;
+
+    /**
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @var boolean
+     */
+    public $required = false;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attributes.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attributes.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Attributes.php	(revision 345)
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the types of all declared attributes during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Attributes
+{
+    /**
+     * @var array<Doctrine\Common\Annotations\Annotation\Attribute>
+     */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser to ignore specific
+ * annotations during the parsing process.
+ *
+ * @Annotation
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class IgnoreAnnotation
+{
+    public $names;
+
+    public function __construct(array $values)
+    {
+        if (is_string($values['value'])) {
+            $values['value'] = array($values['value']);
+        }
+        if (!is_array($values['value'])) {
+            throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value'])));
+        }
+
+        $this->names = $values['value'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Required.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Required.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Required.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check if that attribute is required during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Required
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Target.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Target.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Annotation/Target.php	(revision 345)
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the annotation target during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Target
+{
+    const TARGET_CLASS              = 1;
+    const TARGET_METHOD             = 2;
+    const TARGET_PROPERTY           = 4;
+    const TARGET_ANNOTATION         = 8;
+    const TARGET_ALL                = 15;
+
+    /**
+     * @var array
+     */
+    private static $map = array(
+        'ALL'         => self::TARGET_ALL,
+        'CLASS'       => self::TARGET_CLASS,
+        'METHOD'      => self::TARGET_METHOD,
+        'PROPERTY'    => self::TARGET_PROPERTY,
+        'ANNOTATION'  => self::TARGET_ANNOTATION,
+    );
+
+    /**
+     * @var array
+     */
+    public $value;
+
+    /**
+     * Targets as bitmask.
+     *
+     * @var integer
+     */
+    public $targets;
+
+    /**
+     * Literal target declaration.
+     *
+     * @var integer
+     */
+    public $literal;
+
+    /**
+     * Annotation construct
+     *
+     * @param array $values
+     */
+    public function __construct(array $values)
+    {
+        if (!isset($values['value'])){
+            $values['value'] = null;
+        }
+        if (is_string($values['value'])){
+            $values['value'] = array($values['value']);
+        }
+        if (!is_array($values['value'])){
+            throw new \InvalidArgumentException(
+                sprintf('@Target expects either a string value, or an array of strings, "%s" given.',
+                    is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
+                )
+            );
+        }
+
+        $bitmask = 0;
+        foreach ($values['value'] as $literal) {
+            if(!isset(self::$map[$literal])){
+                throw new \InvalidArgumentException(
+                    sprintf('Invalid Target "%s". Available targets: [%s]',
+                            $literal,  implode(', ', array_keys(self::$map)))
+                );
+            }
+            $bitmask += self::$map[$literal];
+        }
+
+        $this->targets  = $bitmask;
+        $this->value    = $values['value'];
+        $this->literal  = implode(', ', $this->value);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationException.php	(revision 345)
@@ -0,0 +1,111 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Description of AnnotationException
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class AnnotationException extends \Exception
+{
+    /**
+     * Creates a new AnnotationException describing a Syntax error.
+     *
+     * @param string $message Exception message
+     * @return AnnotationException
+     */
+    public static function syntaxError($message)
+    {
+        return new self('[Syntax Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing a Semantical error.
+     *
+     * @param string $message Exception message
+     * @return AnnotationException
+     */
+    public static function semanticalError($message)
+    {
+        return new self('[Semantical Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing an error which occurred during
+     * the creation of the annotation.
+     *
+     * @since 2.2
+     * @param string $message
+     * @return AnnotationException
+     */
+    public static function creationError($message)
+    {
+        return new self('[Creation Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing an type error of an attribute.
+     *
+     * @since 2.2
+     * @param string $attributeName
+     * @param string $annotationName
+     * @param string $context
+     * @param string $expected
+     * @param mixed $actual
+     * @return AnnotationException
+     */
+    public static function typeError($attributeName, $annotationName, $context, $expected, $actual)
+    {
+        return new self(sprintf(
+            '[Type Error] Attribute "%s" of @%s declared on %s expects %s, but got %s.',
+            $attributeName,
+            $annotationName,
+            $context,
+            $expected,
+            is_object($actual) ? 'an instance of '.get_class($actual) : gettype($actual)
+        ));
+    }
+
+    /**
+     * Creates a new AnnotationException describing an required error of an attribute.
+     *
+     * @since 2.2
+     * @param string $attributeName
+     * @param string $annotationName
+     * @param string $context
+     * @param string $expected
+     * @return AnnotationException
+     */
+    public static function requiredError($attributeName, $annotationName, $context, $expected)
+    {
+        return new self(sprintf(
+            '[Type Error] Attribute "%s" of @%s declared on %s expects %s. This value should not be null.',
+            $attributeName,
+            $annotationName,
+            $context,
+            $expected
+        ));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationReader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationReader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationReader.php	(revision 345)
@@ -0,0 +1,301 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
+use Doctrine\Common\Annotations\Annotation\Target;
+use Closure;
+use ReflectionClass;
+use ReflectionMethod;
+use ReflectionProperty;
+
+/**
+ * A reader for docblock annotations.
+ *
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class AnnotationReader implements Reader
+{
+    /**
+     * Global map for imports.
+     *
+     * @var array
+     */
+    private static $globalImports = array(
+        'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation',
+    );
+
+    /**
+     * A list with annotations that are not causing exceptions when not resolved to an annotation class.
+     *
+     * The names are case sensitive.
+     *
+     * @var array
+     */
+    private static $globalIgnoredNames = array(
+        'access'=> true, 'author'=> true, 'copyright'=> true, 'deprecated'=> true,
+        'example'=> true, 'ignore'=> true, 'internal'=> true, 'link'=> true, 'see'=> true,
+        'since'=> true, 'tutorial'=> true, 'version'=> true, 'package'=> true,
+        'subpackage'=> true, 'name'=> true, 'global'=> true, 'param'=> true,
+        'return'=> true, 'staticvar'=> true, 'category'=> true, 'staticVar'=> true,
+        'static'=> true, 'var'=> true, 'throws'=> true, 'inheritdoc'=> true,
+        'inheritDoc'=> true, 'license'=> true, 'todo'=> true, 'deprecated'=> true,
+        'deprec'=> true, 'author'=> true, 'property' => true, 'method' => true,
+        'abstract'=> true, 'exception'=> true, 'magic' => true, 'api' => true,
+        'final'=> true, 'filesource'=> true, 'throw' => true, 'uses' => true,
+        'usedby'=> true, 'private' => true, 'Annotation' => true, 'override' => true,
+        'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true,
+        'Required' => true, 'Attribute' => true, 'Attributes' => true,
+        'Target' => true, 'SuppressWarnings' => true,
+    );
+
+    /**
+     * Add a new annotation to the globally ignored annotation names with regard to exception handling.
+     *
+     * @param string $name
+     */
+    static public function addGlobalIgnoredName($name)
+    {
+        self::$globalIgnoredNames[$name] = true;
+    }
+
+    /**
+     * Annotations Parser
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private $parser;
+
+    /**
+     * Annotations Parser used to collect parsing metadata
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private $preParser;
+
+    /**
+     * PHP Parser used to collect imports.
+     *
+     * @var Doctrine\Common\Annotations\PhpParser
+     */
+    private $phpParser;
+
+    /**
+     * In-memory cache mechanism to store imported annotations per class.
+     *
+     * @var array
+     */
+    private $imports = array();
+
+    /**
+     * In-memory cache mechanism to store ignored annotations per class.
+     *
+     * @var array
+     */
+    private $ignoredAnnotationNames = array();
+
+    /**
+     * Constructor.
+     *
+     * Initializes a new AnnotationReader.
+     */
+    public function __construct()
+    {
+        AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php');
+
+        $this->parser = new DocParser;
+
+        $this->preParser = new DocParser;
+        $this->preParser->setImports(self::$globalImports);
+        $this->preParser->setIgnoreNotImportedAnnotations(true);
+
+        $this->phpParser = new PhpParser;
+    }
+
+    /**
+     * Gets the annotations applied to a class.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getClassAnnotations(ReflectionClass $class)
+    {
+        $this->parser->setTarget(Target::TARGET_CLASS);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(ReflectionClass $class, $annotationName)
+    {
+        $annotations = $this->getClassAnnotations($class);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets the annotations applied to a property.
+     *
+     * @param ReflectionProperty $property The ReflectionProperty of the property
+     *                                     from which the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getPropertyAnnotations(ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $context = 'property ' . $class->getName() . "::\$" . $property->getName();
+        $this->parser->setTarget(Target::TARGET_PROPERTY);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($property->getDocComment(), $context);
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
+    {
+        $annotations = $this->getPropertyAnnotations($property);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets the annotations applied to a method.
+     *
+     * @param ReflectionMethod $property The ReflectionMethod of the method from which
+     *                                   the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getMethodAnnotations(ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
+        $this->parser->setTarget(Target::TARGET_METHOD);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($method->getDocComment(), $context);
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
+    {
+        $annotations = $this->getMethodAnnotations($method);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the ignored annotations for the given class.
+     *
+     * @param ReflectionClass $class
+     * @return array
+     */
+    private function getIgnoredAnnotationNames(ReflectionClass $class)
+    {
+        if (isset($this->ignoredAnnotationNames[$name = $class->getName()])) {
+            return $this->ignoredAnnotationNames[$name];
+        }
+        $this->collectParsingMetadata($class);
+
+        return $this->ignoredAnnotationNames[$name];
+    }
+
+    private function getImports(ReflectionClass $class)
+    {
+        if (isset($this->imports[$name = $class->getName()])) {
+            return $this->imports[$name];
+        }
+        $this->collectParsingMetadata($class);
+
+        return $this->imports[$name];
+    }
+
+    /**
+     * Collects parsing metadata for a given class
+     *
+     * @param ReflectionClass $class
+     */
+    private function collectParsingMetadata(ReflectionClass $class)
+    {
+        $ignoredAnnotationNames = self::$globalIgnoredNames;
+
+        $annotations = $this->preParser->parse($class->getDocComment(), 'class '.$class->name);
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof IgnoreAnnotation) {
+                foreach ($annotation->names AS $annot) {
+                    $ignoredAnnotationNames[$annot] = true;
+                }
+            }
+        }
+
+        $name = $class->getName();
+        $this->imports[$name] = array_merge(
+            self::$globalImports,
+            $this->phpParser->parseClass($class),
+            array('__NAMESPACE__' => $class->getNamespaceName())
+        );
+        $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationRegistry.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationRegistry.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/AnnotationRegistry.php	(revision 345)
@@ -0,0 +1,129 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+final class AnnotationRegistry
+{
+    /**
+     * A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
+     *
+     * Contains the namespace as key and an array of directories as value. If the value is NULL
+     * the include path is used for checking for the corresponding file.
+     *
+     * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
+     *
+     * @var array
+     */
+    static private $autoloadNamespaces = array();
+
+    /**
+     * A map of autoloader callables.
+     *
+     * @var array
+     */
+    static private $loaders = array();
+
+    static public function reset()
+    {
+        self::$autoloadNamespaces = array();
+        self::$loaders = array();
+    }
+
+    static public function registerFile($file)
+    {
+        require_once $file;
+    }
+
+    /**
+     * Add a namespace with one or many directories to look for files or null for the include path.
+     *
+     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
+     *
+     * @param string $namespace
+     * @param string|array|null $dirs
+     */
+    static public function registerAutoloadNamespace($namespace, $dirs = null)
+    {
+        self::$autoloadNamespaces[$namespace] = $dirs;
+    }
+
+    /**
+     * Register multiple namespaces
+     *
+     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
+     *
+     * @param array $namespaces
+     */
+    static public function registerAutoloadNamespaces(array $namespaces)
+    {
+        self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
+    }
+
+    /**
+     * Register an autoloading callabale for annotations, much like spl_autoload_register().
+     *
+     * NOTE: These class loaders HAVE to be silent when a class was not found!
+     * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
+     *
+     * @param callabale $callabale
+     */
+    static public function registerLoader($callabale)
+    {
+        if (!is_callable($callabale)) {
+            throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader().");
+        }
+        self::$loaders[] = $callabale;
+    }
+
+    /**
+     * Autoload an annotation class silently.
+     *
+     * @param string $class
+     * @return void
+     */
+    static public function loadAnnotationClass($class)
+    {
+        foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
+            if (strpos($class, $namespace) === 0) {
+                $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php";
+                if ($dirs === null) {
+                    if ($path = stream_resolve_include_path($file)) {
+                        require $path;
+                        return true;
+                    }
+                } else {
+                    foreach((array)$dirs AS $dir) {
+                        if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) {
+                            require $dir . DIRECTORY_SEPARATOR . $file;
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        foreach (self::$loaders AS $loader) {
+            if (call_user_func($loader, $class) === true) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/CachedReader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/CachedReader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/CachedReader.php	(revision 345)
@@ -0,0 +1,179 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * A cache aware annotation reader.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+final class CachedReader implements Reader
+{
+    private static $CACHE_SALT = '@[Annot]';
+
+    /**
+     * @var Reader
+     */
+    private $delegate;
+
+    /**
+     * @var Cache
+     */
+    private $cache;
+
+    /**
+     * @var boolean
+     */
+    private $debug;
+
+    /**
+     * @var array
+     */
+    private $loadedAnnotations;
+
+    /**
+     * @param Reader $reader
+     * @param Cache $cache
+     */
+    public function __construct(Reader $reader, Cache $cache, $debug = false)
+    {
+        $this->delegate = $reader;
+        $this->cache = $cache;
+        $this->debug = $debug;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $cacheKey = $class->getName() . self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+        // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getClassAnnotations($class);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        foreach ($this->getClassAnnotations($class) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $cacheKey = $class->getName().'$'.$property->getName().self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+        // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getPropertyAnnotations($property);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        foreach ($this->getPropertyAnnotations($property) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $cacheKey = $class->getName().'#'.$method->getName().self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+       // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getMethodAnnotations($method);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        foreach ($this->getMethodAnnotations($method) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function clearLoadedAnnotations()
+    {
+        $this->loadedAnnotations = array();
+    }
+
+    private function isCacheFresh($cacheKey, \ReflectionClass $class)
+    {
+        if (false === $filename = $class->getFilename()) {
+            return true;
+        }
+
+        return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocLexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocLexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocLexer.php	(revision 345)
@@ -0,0 +1,140 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Lexer;
+
+/**
+ * Simple lexer for docblock annotations.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class DocLexer extends Lexer
+{
+    const T_NONE                = 1;
+    const T_IDENTIFIER          = 2;
+    const T_INTEGER             = 3;
+    const T_STRING              = 4;
+    const T_FLOAT               = 5;
+
+    const T_AT                  = 101;
+    const T_CLOSE_CURLY_BRACES  = 102;
+    const T_CLOSE_PARENTHESIS   = 103;
+    const T_COMMA               = 104;
+    const T_EQUALS              = 105;
+    const T_FALSE               = 106;
+    const T_NAMESPACE_SEPARATOR = 107;
+    const T_OPEN_CURLY_BRACES   = 108;
+    const T_OPEN_PARENTHESIS    = 109;
+    const T_TRUE                = 110;
+    const T_NULL                = 111;
+    const T_COLON               = 112;
+
+    /**
+     * @inheritdoc
+     */
+    protected function getCatchablePatterns()
+    {
+        return array(
+            '[a-z_][a-z0-9_:]*',
+            '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?',
+            '"(?:[^"]|"")*"',
+        );
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getNonCatchablePatterns()
+    {
+        return array('\s+', '\*+', '(.)');
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getType(&$value)
+    {
+        $type = self::T_NONE;
+
+        // Checking numeric value
+        if (is_numeric($value)) {
+            return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
+                ? self::T_FLOAT : self::T_INTEGER;
+        }
+
+        if ($value[0] === '"') {
+            $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
+
+            return self::T_STRING;
+        } else {
+            switch (strtolower($value)) {
+                case '@':
+                    return self::T_AT;
+
+                case ',':
+                    return self::T_COMMA;
+
+                case '(':
+                    return self::T_OPEN_PARENTHESIS;
+
+                case ')':
+                    return self::T_CLOSE_PARENTHESIS;
+
+                case '{':
+                    return self::T_OPEN_CURLY_BRACES;
+
+                case '}':
+                    return self::T_CLOSE_CURLY_BRACES;
+
+                case '=':
+                    return self::T_EQUALS;
+
+                case '\\':
+                    return self::T_NAMESPACE_SEPARATOR;
+
+                case 'true':
+                    return self::T_TRUE;
+
+                case 'false':
+                    return self::T_FALSE;
+
+                case 'null':
+                    return self::T_NULL;
+
+                case ':':
+                    return self::T_COLON;
+
+                default:
+                    if (ctype_alpha($value[0]) || $value[0] === '_') {
+                        return self::T_IDENTIFIER;
+                    }
+
+                    break;
+            }
+        }
+
+        return $type;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocParser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocParser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/DocParser.php	(revision 345)
@@ -0,0 +1,891 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Closure;
+use ReflectionClass;
+use Doctrine\Common\Annotations\Annotation\Target;
+use Doctrine\Common\Annotations\Annotation\Attribute;
+use Doctrine\Common\Annotations\Annotation\Attributes;
+
+/**
+ * A parser for docblock annotations.
+ *
+ * It is strongly discouraged to change the default annotation parsing process.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+final class DocParser
+{
+    /**
+     * An array of all valid tokens for a class name.
+     *
+     * @var array
+     */
+    private static $classIdentifiers = array(DocLexer::T_IDENTIFIER, DocLexer::T_TRUE, DocLexer::T_FALSE, DocLexer::T_NULL);
+
+    /**
+     * The lexer.
+     *
+     * @var Doctrine\Common\Annotations\DocLexer
+     */
+    private $lexer;
+
+    /**
+     * Current target context
+     *
+     * @var string
+     */
+    private $target;
+
+    /**
+     * Doc Parser used to collect annotation target
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private static $metadataParser;
+
+    /**
+     * Flag to control if the current annotation is nested or not.
+     *
+     * @var boolean
+     */
+    private $isNestedAnnotation = false;
+
+    /**
+     * Hashmap containing all use-statements that are to be used when parsing
+     * the given doc block.
+     *
+     * @var array
+     */
+    private $imports = array();
+
+    /**
+     * This hashmap is used internally to cache results of class_exists()
+     * look-ups.
+     *
+     * @var array
+     */
+    private $classExists = array();
+
+    /**
+     * Whether annotations that have not been imported should be ignored.
+     *
+     * @var boolean
+     */
+    private $ignoreNotImportedAnnotations = false;
+
+    /**
+     * An array of default namespaces if operating in simple mode.
+     *
+     * @var array
+     */
+    private $namespaces = array();
+
+    /**
+     * A list with annotations that are not causing exceptions when not resolved to an annotation class.
+     *
+     * The names must be the raw names as used in the class, not the fully qualified
+     * class names.
+     *
+     * @var array
+     */
+    private $ignoredAnnotationNames = array();
+
+    /**
+     * @var string
+     */
+    private $context = '';
+
+    /**
+     * Hash-map for caching annotation metadata
+     * @var array
+     */
+    private static $annotationMetadata = array(
+        'Doctrine\Common\Annotations\Annotation\Target' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => true,
+            'properties'       => array(),
+            'targets_literal'  => 'ANNOTATION_CLASS',
+            'targets'          => Target::TARGET_CLASS,
+            'default_property' => 'value',
+            'attribute_types'  => array(
+                'value'  => array(
+                    'required'  => false,
+                    'type'      =>'array',
+                    'array_type'=>'string',
+                    'value'     =>'array<string>'
+                )
+             ),
+        ),
+        'Doctrine\Common\Annotations\Annotation\Attribute' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => false,
+            'targets_literal'  => 'ANNOTATION_ANNOTATION',
+            'targets'          => Target::TARGET_ANNOTATION,
+            'default_property' => 'name',
+            'properties'       => array(
+                'name'      => 'name',
+                'type'      => 'type',
+                'required'  => 'required'
+            ),
+            'attribute_types'  => array(
+                'value'  => array(
+                    'required'  => true,
+                    'type'      =>'string',
+                    'value'     =>'string'
+                ),
+                'type'  => array(
+                    'required'  =>true,
+                    'type'      =>'string',
+                    'value'     =>'string'
+                ),
+                'required'  => array(
+                    'required'  =>false,
+                    'type'      =>'boolean',
+                    'value'     =>'boolean'
+                )
+             ),
+        ),
+        'Doctrine\Common\Annotations\Annotation\Attributes' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => false,
+            'targets_literal'  => 'ANNOTATION_CLASS',
+            'targets'          => Target::TARGET_CLASS,
+            'default_property' => 'value',
+            'properties'       => array(
+                'value' => 'value'
+            ),
+            'attribute_types'  => array(
+                'value' => array(
+                    'type'      =>'array',
+                    'required'  =>true,
+                    'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute',
+                    'value'     =>'array<Doctrine\Common\Annotations\Annotation\Attribute>'
+                )
+             ),
+        ),
+    );
+
+    /**
+     * Hash-map for handle types declaration
+     *
+     * @var array
+     */
+    private static $typeMap = array(
+        'float'     => 'double',
+        'bool'      => 'boolean',
+        // allow uppercase Boolean in honor of George Boole
+        'Boolean'   => 'boolean',
+        'int'       => 'integer',
+    );
+
+    /**
+     * Constructs a new DocParser.
+     */
+    public function __construct()
+    {
+        $this->lexer = new DocLexer;
+    }
+
+    /**
+     * Sets the annotation names that are ignored during the parsing process.
+     *
+     * The names are supposed to be the raw names as used in the class, not the
+     * fully qualified class names.
+     *
+     * @param array $names
+     */
+    public function setIgnoredAnnotationNames(array $names)
+    {
+        $this->ignoredAnnotationNames = $names;
+    }
+
+    public function setIgnoreNotImportedAnnotations($bool)
+    {
+        $this->ignoreNotImportedAnnotations = (Boolean) $bool;
+    }
+
+    /**
+     * Sets the default namespaces.
+     * @param array $namespaces
+     */
+    public function addNamespace($namespace)
+    {
+        if ($this->imports) {
+            throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.');
+        }
+        $this->namespaces[] = $namespace;
+    }
+
+    public function setImports(array $imports)
+    {
+        if ($this->namespaces) {
+            throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.');
+        }
+        $this->imports = $imports;
+    }
+
+     /**
+     * Sets current target context as bitmask.
+     *
+     * @param integer $target
+     */
+    public function setTarget($target)
+    {
+        $this->target = $target;
+    }
+
+    /**
+     * Parses the given docblock string for annotations.
+     *
+     * @param string $input The docblock string to parse.
+     * @param string $context The parsing context.
+     * @return array Array of annotations. If no annotations are found, an empty array is returned.
+     */
+    public function parse($input, $context = '')
+    {
+        if (false === $pos = strpos($input, '@')) {
+            return array();
+        }
+
+        // also parse whatever character is before the @
+        if ($pos > 0) {
+            $pos -= 1;
+        }
+
+        $this->context = $context;
+        $this->lexer->setInput(trim(substr($input, $pos), '* /'));
+        $this->lexer->moveNext();
+
+        return $this->Annotations();
+    }
+
+    /**
+     * Attempts to match the given token with the current lookahead token.
+     * If they match, updates the lookahead token; otherwise raises a syntax error.
+     *
+     * @param int Token type.
+     * @return bool True if tokens match; false otherwise.
+     */
+    private function match($token)
+    {
+        if ( ! $this->lexer->isNextToken($token) ) {
+            $this->syntaxError($this->lexer->getLiteral($token));
+        }
+
+        return $this->lexer->moveNext();
+    }
+
+    /**
+     * Attempts to match the current lookahead token with any of the given tokens.
+     *
+     * If any of them matches, this method updates the lookahead token; otherwise
+     * a syntax error is raised.
+     *
+     * @param array $tokens
+     * @return bool
+     */
+    private function matchAny(array $tokens)
+    {
+        if ( ! $this->lexer->isNextTokenAny($tokens)) {
+            $this->syntaxError(implode(' or ', array_map(array($this->lexer, 'getLiteral'), $tokens)));
+        }
+
+        return $this->lexer->moveNext();
+    }
+
+    /**
+     * Generates a new syntax error.
+     *
+     * @param string $expected Expected string.
+     * @param array $token Optional token.
+     * @throws SyntaxException
+     */
+    private function syntaxError($expected, $token = null)
+    {
+        if ($token === null) {
+            $token = $this->lexer->lookahead;
+        }
+
+        $message =  "Expected {$expected}, got ";
+
+        if ($this->lexer->lookahead === null) {
+            $message .= 'end of string';
+        } else {
+            $message .= "'{$token['value']}' at position {$token['position']}";
+        }
+
+        if (strlen($this->context)) {
+            $message .= ' in ' . $this->context;
+        }
+
+        $message .= '.';
+
+        throw AnnotationException::syntaxError($message);
+    }
+
+    /**
+     * Attempt to check if a class exists or not. This never goes through the PHP autoloading mechanism
+     * but uses the {@link AnnotationRegistry} to load classes.
+     *
+     * @param string $fqcn
+     * @return boolean
+     */
+    private function classExists($fqcn)
+    {
+        if (isset($this->classExists[$fqcn])) {
+            return $this->classExists[$fqcn];
+        }
+
+        // first check if the class already exists, maybe loaded through another AnnotationReader
+        if (class_exists($fqcn, false)) {
+            return $this->classExists[$fqcn] = true;
+        }
+
+        // final check, does this class exist?
+        return $this->classExists[$fqcn] = AnnotationRegistry::loadAnnotationClass($fqcn);
+    }
+
+    /**
+     * Collects parsing metadata for a given annotation class
+     *
+     * @param   string $name        The annotation name
+     */
+    private function collectAnnotationMetadata($name)
+    {
+        if (self::$metadataParser == null){
+            self::$metadataParser = new self();
+            self::$metadataParser->setTarget(Target::TARGET_CLASS);
+            self::$metadataParser->setIgnoreNotImportedAnnotations(true);
+            self::$metadataParser->setImports(array(
+                'target'        => 'Doctrine\Common\Annotations\Annotation\Target',
+                'attribute'     => 'Doctrine\Common\Annotations\Annotation\Attribute',
+                'attributes'    => 'Doctrine\Common\Annotations\Annotation\Attributes'
+            ));
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php');
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php');
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php');
+        }
+
+        $class      = new \ReflectionClass($name);
+        $docComment = $class->getDocComment();
+
+        // Sets default values for annotation metadata
+        $metadata = array(
+            'default_property' => null,
+            'has_constructor'  => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0,
+            'properties'       => array(),
+            'property_types'   => array(),
+            'attribute_types'  => array(),
+            'targets_literal'  => null,
+            'targets'          => Target::TARGET_ALL,
+            'is_annotation'    => false !== strpos($docComment, '@Annotation'),
+        );
+
+        // verify that the class is really meant to be an annotation
+        if ($metadata['is_annotation']) {
+            foreach (self::$metadataParser->parse($docComment, 'class @' . $name) as $annotation) {
+                if ($annotation instanceof Target) {
+                    $metadata['targets']         = $annotation->targets;
+                    $metadata['targets_literal'] = $annotation->literal;
+
+                } elseif ($annotation instanceof Attributes) {
+                    foreach ($annotation->value as $attrib) {
+                        // handle internal type declaration
+                        $type = isset(self::$typeMap[$attrib->type]) ? self::$typeMap[$attrib->type] : $attrib->type;
+
+                        // handle the case if the property type is mixed
+                        if ('mixed' !== $type) {
+                            // Checks if the property has array<type>
+                            if (false !== $pos = strpos($type, '<')) {
+                                $arrayType  = substr($type, $pos+1, -1);
+                                $type       = 'array';
+
+                                if (isset(self::$typeMap[$arrayType])) {
+                                    $arrayType = self::$typeMap[$arrayType];
+                                }
+
+                                $metadata['attribute_types'][$attrib->name]['array_type'] = $arrayType;
+                            }
+
+                            $metadata['attribute_types'][$attrib->name]['type']     = $type;
+                            $metadata['attribute_types'][$attrib->name]['value']    = $attrib->type;
+                            $metadata['attribute_types'][$attrib->name]['required'] = $attrib->required;
+                        }
+                    }
+                }
+            }
+
+            // if not has a constructor will inject values into public properties
+            if (false === $metadata['has_constructor']) {
+                // collect all public properties
+                foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
+                    $metadata['properties'][$property->name] = $property->name;
+
+                    // checks if the property has @var annotation
+                    if ((false !== $propertyComment = $property->getDocComment())
+                        && false !== strpos($propertyComment, '@var')
+                        && preg_match('/@var\s+([^\s]+)/',$propertyComment, $matches)) {
+                        // literal type declaration
+                        $value = $matches[1];
+
+                        // handle internal type declaration
+                        $type = isset(self::$typeMap[$value]) ? self::$typeMap[$value] : $value;
+
+                        // handle the case if the property type is mixed
+                        if ('mixed' !== $type) {
+                            // Checks if the property has @var array<type> annotation
+                            if (false !== $pos = strpos($type, '<')) {
+                                $arrayType = substr($type, $pos+1, -1);
+                                $type = 'array';
+
+                                if (isset(self::$typeMap[$arrayType])) {
+                                    $arrayType = self::$typeMap[$arrayType];
+                                }
+
+                                $metadata['attribute_types'][$property->name]['array_type'] = $arrayType;
+                            }
+
+                            $metadata['attribute_types'][$property->name]['type']       = $type;
+                            $metadata['attribute_types'][$property->name]['value']      = $value;
+                            $metadata['attribute_types'][$property->name]['required']   = false !== strpos($propertyComment, '@Required');
+                        }
+                    }
+                }
+
+                // choose the first property as default property
+                $metadata['default_property'] = reset($metadata['properties']);
+            }
+        }
+
+        self::$annotationMetadata[$name] = $metadata;
+    }
+
+    /**
+     * Annotations ::= Annotation {[ "*" ]* [Annotation]}*
+     *
+     * @return array
+     */
+    private function Annotations()
+    {
+        $annotations = array();
+
+        while (null !== $this->lexer->lookahead) {
+            if (DocLexer::T_AT !== $this->lexer->lookahead['type']) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            // make sure the @ is preceded by non-catchable pattern
+            if (null !== $this->lexer->token && $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value'])) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            // make sure the @ is followed by either a namespace separator, or
+            // an identifier token
+            if ((null === $peek = $this->lexer->glimpse())
+                || (DocLexer::T_NAMESPACE_SEPARATOR !== $peek['type'] && !in_array($peek['type'], self::$classIdentifiers, true))
+                || $peek['position'] !== $this->lexer->lookahead['position'] + 1) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            $this->isNestedAnnotation = false;
+            if (false !== $annot = $this->Annotation()) {
+                $annotations[] = $annot;
+            }
+        }
+
+        return $annotations;
+    }
+
+    /**
+     * Annotation     ::= "@" AnnotationName ["(" [Values] ")"]
+     * AnnotationName ::= QualifiedName | SimpleName
+     * QualifiedName  ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName
+     * NameSpacePart  ::= identifier | null | false | true
+     * SimpleName     ::= identifier | null | false | true
+     *
+     * @return mixed False if it is not a valid annotation.
+     */
+    private function Annotation()
+    {
+        $this->match(DocLexer::T_AT);
+
+        // check if we have an annotation
+        if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) {
+            $this->lexer->moveNext();
+            $name = $this->lexer->token['value'];
+        } else if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) {
+            $name = '';
+        } else {
+            $this->syntaxError('namespace separator or identifier');
+        }
+
+        while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) {
+            $this->match(DocLexer::T_NAMESPACE_SEPARATOR);
+            $this->matchAny(self::$classIdentifiers);
+            $name .= '\\'.$this->lexer->token['value'];
+        }
+
+        // only process names which are not fully qualified, yet
+        // fully qualified names must start with a \
+        $originalName = $name;
+        if ('\\' !== $name[0]) {
+            $alias = (false === $pos = strpos($name, '\\'))? $name : substr($name, 0, $pos);
+
+            $found = false;
+            if ($this->namespaces) {
+                foreach ($this->namespaces as $namespace) {
+                    if ($this->classExists($namespace.'\\'.$name)) {
+                        $name = $namespace.'\\'.$name;
+                        $found = true;
+                        break;
+                    }
+                }
+            } elseif (isset($this->imports[$loweredAlias = strtolower($alias)])) {
+                if (false !== $pos) {
+                    $name = $this->imports[$loweredAlias].substr($name, $pos);
+                } else {
+                    $name = $this->imports[$loweredAlias];
+                }
+                $found = true;
+            } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'].'\\'.$name)) {
+                 $name = $this->imports['__NAMESPACE__'].'\\'.$name;
+                 $found = true;
+            } elseif ($this->classExists($name)) {
+                $found = true;
+            }
+
+            if (!$found) {
+                if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) {
+                    return false;
+                }
+
+                throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context));
+            }
+        }
+
+        if (!$this->classExists($name)) {
+            throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context));
+        }
+
+        // at this point, $name contains the fully qualified class name of the
+        // annotation, and it is also guaranteed that this class exists, and
+        // that it is loaded
+
+
+        // collects the metadata annotation only if there is not yet
+        if (!isset(self::$annotationMetadata[$name])) {
+            $this->collectAnnotationMetadata($name);
+        }
+
+        // verify that the class is really meant to be an annotation and not just any ordinary class
+        if (self::$annotationMetadata[$name]['is_annotation'] === false) {
+            if (isset($this->ignoredAnnotationNames[$originalName])) {
+                return false;
+            }
+
+            throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context));
+        }
+
+        //if target is nested annotation
+        $target = $this->isNestedAnnotation ? Target::TARGET_ANNOTATION : $this->target;
+
+        // Next will be nested
+        $this->isNestedAnnotation = true;
+
+        //if annotation does not support current target
+        if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) {
+            throw AnnotationException::semanticalError(
+                sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.',
+                     $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal'])
+            );
+        }
+
+        $values = array();
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) {
+            $this->match(DocLexer::T_OPEN_PARENTHESIS);
+
+            if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) {
+                $values = $this->Values();
+            }
+
+            $this->match(DocLexer::T_CLOSE_PARENTHESIS);
+        }
+
+        // checks all declared attributes
+        foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) {
+            if ($property === self::$annotationMetadata[$name]['default_property']
+                && !isset($values[$property]) && isset($values['value'])) {
+                $property = 'value';
+            }
+
+            // handle a not given attribute or null value
+            if (!isset($values[$property])) {
+                if ($type['required']) {
+                    throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) '.$type['value']);
+                }
+
+                continue;
+            }
+
+            if ($type['type'] === 'array') {
+                // handle the case of a single value
+                if (!is_array($values[$property])) {
+                    $values[$property] = array($values[$property]);
+                }
+
+                // checks if the attribute has array type declaration, such as "array<string>"
+                if (isset($type['array_type'])) {
+                    foreach ($values[$property] as $item) {
+                        if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) {
+                            throw AnnotationException::typeError($property, $originalName, $this->context, 'either a(n) '.$type['array_type'].', or an array of '.$type['array_type'].'s', $item);
+                        }
+                    }
+                }
+            } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) {
+                throw AnnotationException::typeError($property, $originalName, $this->context, 'a(n) '.$type['value'], $values[$property]);
+            }
+        }
+
+        // check if the annotation expects values via the constructor,
+        // or directly injected into public properties
+        if (self::$annotationMetadata[$name]['has_constructor'] === true) {
+            return new $name($values);
+        }
+
+        $instance = new $name();
+        foreach ($values as $property => $value) {
+            if (!isset(self::$annotationMetadata[$name]['properties'][$property])) {
+                if ('value' !== $property) {
+                    throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties'])));
+                }
+
+                // handle the case if the property has no annotations
+                if (!$property = self::$annotationMetadata[$name]['default_property']) {
+                    throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values)));
+                }
+            }
+
+            $instance->{$property} = $value;
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Values ::= Array | Value {"," Value}*
+     *
+     * @return array
+     */
+    private function Values()
+    {
+        $values = array();
+
+        // Handle the case of a single array as value, i.e. @Foo({....})
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) {
+            $values['value'] = $this->Value();
+            return $values;
+        }
+
+        $values[] = $this->Value();
+
+        while ($this->lexer->isNextToken(DocLexer::T_COMMA)) {
+            $this->match(DocLexer::T_COMMA);
+            $token = $this->lexer->lookahead;
+            $value = $this->Value();
+
+            if ( ! is_object($value) && ! is_array($value)) {
+                $this->syntaxError('Value', $token);
+            }
+
+            $values[] = $value;
+        }
+
+        foreach ($values as $k => $value) {
+            if (is_object($value) && $value instanceof \stdClass) {
+                $values[$value->name] = $value->value;
+            } else if ( ! isset($values['value'])){
+                $values['value'] = $value;
+            } else {
+                if ( ! is_array($values['value'])) {
+                    $values['value'] = array($values['value']);
+                }
+
+                $values['value'][] = $value;
+            }
+
+            unset($values[$k]);
+        }
+
+        return $values;
+    }
+
+    /**
+     * Value ::= PlainValue | FieldAssignment
+     *
+     * @return mixed
+     */
+    private function Value()
+    {
+        $peek = $this->lexer->glimpse();
+
+        if (DocLexer::T_EQUALS === $peek['type']) {
+            return $this->FieldAssignment();
+        }
+
+        return $this->PlainValue();
+    }
+
+    /**
+     * PlainValue ::= integer | string | float | boolean | Array | Annotation
+     *
+     * @return mixed
+     */
+    private function PlainValue()
+    {
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) {
+            return $this->Arrayx();
+        }
+
+        if ($this->lexer->isNextToken(DocLexer::T_AT)) {
+            return $this->Annotation();
+        }
+
+        switch ($this->lexer->lookahead['type']) {
+            case DocLexer::T_STRING:
+                $this->match(DocLexer::T_STRING);
+                return $this->lexer->token['value'];
+
+            case DocLexer::T_INTEGER:
+                $this->match(DocLexer::T_INTEGER);
+                return (int)$this->lexer->token['value'];
+
+            case DocLexer::T_FLOAT:
+                $this->match(DocLexer::T_FLOAT);
+                return (float)$this->lexer->token['value'];
+
+            case DocLexer::T_TRUE:
+                $this->match(DocLexer::T_TRUE);
+                return true;
+
+            case DocLexer::T_FALSE:
+                $this->match(DocLexer::T_FALSE);
+                return false;
+
+            case DocLexer::T_NULL:
+                $this->match(DocLexer::T_NULL);
+                return null;
+
+            default:
+                $this->syntaxError('PlainValue');
+        }
+    }
+
+    /**
+     * FieldAssignment ::= FieldName "=" PlainValue
+     * FieldName ::= identifier
+     *
+     * @return array
+     */
+    private function FieldAssignment()
+    {
+        $this->match(DocLexer::T_IDENTIFIER);
+        $fieldName = $this->lexer->token['value'];
+
+        $this->match(DocLexer::T_EQUALS);
+
+        $item = new \stdClass();
+        $item->name  = $fieldName;
+        $item->value = $this->PlainValue();
+
+        return $item;
+    }
+
+    /**
+     * Array ::= "{" ArrayEntry {"," ArrayEntry}* [","] "}"
+     *
+     * @return array
+     */
+    private function Arrayx()
+    {
+        $array = $values = array();
+
+        $this->match(DocLexer::T_OPEN_CURLY_BRACES);
+        $values[] = $this->ArrayEntry();
+
+        while ($this->lexer->isNextToken(DocLexer::T_COMMA)) {
+            $this->match(DocLexer::T_COMMA);
+
+            // optional trailing comma
+            if ($this->lexer->isNextToken(DocLexer::T_CLOSE_CURLY_BRACES)) {
+                break;
+            }
+
+            $values[] = $this->ArrayEntry();
+        }
+
+        $this->match(DocLexer::T_CLOSE_CURLY_BRACES);
+
+        foreach ($values as $value) {
+            list ($key, $val) = $value;
+
+            if ($key !== null) {
+                $array[$key] = $val;
+            } else {
+                $array[] = $val;
+            }
+        }
+
+        return $array;
+    }
+
+    /**
+     * ArrayEntry ::= Value | KeyValuePair
+     * KeyValuePair ::= Key ("=" | ":") PlainValue
+     * Key ::= string | integer
+     *
+     * @return array
+     */
+    private function ArrayEntry()
+    {
+        $peek = $this->lexer->glimpse();
+
+        if (DocLexer::T_EQUALS === $peek['type']
+                || DocLexer::T_COLON === $peek['type']) {
+            $this->matchAny(array(DocLexer::T_INTEGER, DocLexer::T_STRING));
+
+            $key = $this->lexer->token['value'];
+            $this->matchAny(array(DocLexer::T_EQUALS, DocLexer::T_COLON));
+
+            return array($key, $this->PlainValue());
+        }
+
+        return array(null, $this->Value());
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/FileCacheReader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/FileCacheReader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/FileCacheReader.php	(revision 345)
@@ -0,0 +1,209 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+
+/**
+ * File cache reader for annotations.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class FileCacheReader implements Reader
+{
+    /**
+     * @var Reader
+     */
+    private $reader;
+    private $dir;
+    private $debug;
+    private $loadedAnnotations = array();
+
+    public function __construct(Reader $reader, $cacheDir, $debug = false)
+    {
+        $this->reader = $reader;
+        if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) {
+            throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
+        }
+        if (!is_writable($cacheDir)) {
+            throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir));
+        }
+
+        $this->dir   = rtrim($cacheDir, '\\/');
+        $this->debug = $debug;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $key = $class->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getClassAnnotations($class);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            @unlink($path);
+
+            $annot = $this->reader->getClassAnnotations($class);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $key = $class->getName().'$'.$property->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getPropertyAnnotations($property);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            unlink($path);
+
+            $annot = $this->reader->getPropertyAnnotations($property);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $key = $class->getName().'#'.$method->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getMethodAnnotations($method);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            unlink($path);
+
+            $annot = $this->reader->getMethodAnnotations($method);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    private function saveCacheFile($path, $data)
+    {
+        file_put_contents($path, '<?php return unserialize('.var_export(serialize($data), true).');');
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        $annotations = $this->getClassAnnotations($class);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        $annotations = $this->getMethodAnnotations($method);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        $annotations = $this->getPropertyAnnotations($property);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    public function clearLoadedAnnotations()
+    {
+        $this->loadedAnnotations = array();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/IndexedReader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/IndexedReader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/IndexedReader.php	(revision 345)
@@ -0,0 +1,94 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Reader;
+
+/**
+ * Allows the reader to be used in-place of Doctrine's reader.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class IndexedReader implements Reader
+{
+    private $delegate;
+
+    public function __construct(Reader $reader)
+    {
+        $this->delegate = $reader;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getClassAnnotations($class) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getClassAnnotation(\ReflectionClass $class, $annotation)
+    {
+        return $this->delegate->getClassAnnotation($class, $annotation);
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getMethodAnnotations($method) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotation)
+    {
+        return $this->delegate->getMethodAnnotation($method, $annotation);
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getPropertyAnnotations($property) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotation)
+    {
+        return $this->delegate->getPropertyAnnotation($property, $annotation);
+    }
+
+    /**
+     * Proxy all methods to the delegate.
+     *
+     * @param type $method
+     * @param type $args
+     * @return type
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->delegate, $method), $args);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/PhpParser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/PhpParser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/PhpParser.php	(revision 345)
@@ -0,0 +1,203 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use SplFileObject;
+
+/**
+ * Parses a file for namespaces/use/class declarations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Christian Kaps <christian.kaps@mohiva.com>
+ */
+final class PhpParser
+{
+    /**
+     * The token list.
+     *
+     * @var array
+     */
+    private $tokens;
+
+    /**
+     * The number of tokens.
+     *
+     * @var int
+     */
+    private $numTokens = 0;
+
+    /**
+     * The current array pointer.
+     *
+     * @var int
+     */
+    private $pointer = 0;
+
+    /**
+     * Parses a class.
+     *
+     * @param \ReflectionClass $class A <code>ReflectionClass</code> object.
+     * @return array A list with use statements in the form (Alias => FQN).
+     */
+    public function parseClass(\ReflectionClass $class)
+    {
+        if (false === $filename = $class->getFilename()) {
+            return array();
+        }
+
+        $content = $this->getFileContent($filename, $class->getStartLine());
+        $namespace = str_replace('\\', '\\\\', $class->getNamespaceName());
+        $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
+        $this->tokens = token_get_all('<?php ' . $content);
+        $this->numTokens = count($this->tokens);
+        $this->pointer = 0;
+
+        $statements = $this->parseUseStatements($class->getNamespaceName());
+
+        return $statements;
+    }
+
+    /**
+     * Get the content of the file right up to the given line number.
+     *
+     * @param string $filename The name of the file to load.
+     * @param int $lineNumber The number of lines to read from file.
+     * @return string The content of the file.
+     */
+    private function getFileContent($filename, $lineNumber)
+    {
+        $content = '';
+        $lineCnt = 0;
+        $file = new SplFileObject($filename);
+        while(!$file->eof()) {
+            if ($lineCnt++ == $lineNumber) {
+                break;
+            }
+
+            $content .= $file->fgets();
+        }
+
+        return $content;
+    }
+
+    /**
+     * Gets the next non whitespace and non comment token.
+     *
+     * @return array The token if exists, null otherwise.
+     */
+    private function next()
+    {
+        for ($i = $this->pointer; $i < $this->numTokens; $i++) {
+            $this->pointer++;
+            if ($this->tokens[$i][0] === T_WHITESPACE ||
+                $this->tokens[$i][0] === T_COMMENT ||
+                $this->tokens[$i][0] === T_DOC_COMMENT) {
+
+                continue;
+            }
+
+            return $this->tokens[$i];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all use statements.
+     *
+     * @param string $namespaceName The namespace name of the reflected class.
+     * @return array A list with all found use statements.
+     */
+    private function parseUseStatements($namespaceName)
+    {
+        $statements = array();
+        while (($token = $this->next())) {
+            if ($token[0] === T_USE) {
+                $statements = array_merge($statements, $this->parseUseStatement());
+                continue;
+            } else if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) {
+                continue;
+            }
+
+            // Get fresh array for new namespace. This is to prevent the parser to collect the use statements
+            // for a previous namespace with the same name. This is the case if a namespace is defined twice
+            // or if a namespace with the same name is commented out.
+            $statements = array();
+        }
+
+        return $statements;
+    }
+
+    /**
+     * Get the namespace name.
+     *
+     * @return string The found namespace name.
+     */
+    private function parseNamespace()
+    {
+        $namespace = '';
+        while (($token = $this->next())){
+            if ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR) {
+                $namespace .= $token[1];
+            } else {
+                break;
+            }
+        }
+
+        return $namespace;
+    }
+
+    /**
+     * Parse a single use statement.
+     *
+     * @return array A list with all found class names for a use statement.
+     */
+    private function parseUseStatement()
+    {
+        $class = '';
+        $alias = '';
+        $statements = array();
+        $explicitAlias = false;
+        while (($token = $this->next())) {
+            $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
+            if (!$explicitAlias && $isNameToken) {
+                $class .= $token[1];
+                $alias = $token[1];
+            } else if ($explicitAlias && $isNameToken) {
+                $alias .= $token[1];
+            } else if ($token[0] === T_AS) {
+                $explicitAlias = true;
+                $alias = '';
+            } else if ($token === ',') {
+                $statements[strtolower($alias)] = $class;
+                $class = '';
+                $alias = '';
+                $explicitAlias = false;
+            } else if ($token === ';') {
+                $statements[strtolower($alias)] = $class;
+                break;
+            } else {
+                break;
+            }
+        }
+
+        return $statements;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Reader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Reader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/Reader.php	(revision 345)
@@ -0,0 +1,35 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Interface for annotation readers.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface Reader
+{
+    function getClassAnnotations(\ReflectionClass $class);
+    function getClassAnnotation(\ReflectionClass $class, $annotationName);
+    function getMethodAnnotations(\ReflectionMethod $method);
+    function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
+    function getPropertyAnnotations(\ReflectionProperty $property);
+    function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/SimpleAnnotationReader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/SimpleAnnotationReader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Annotations/SimpleAnnotationReader.php	(revision 345)
@@ -0,0 +1,152 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Annotation\Target;
+
+/**
+ * Simple Annotation Reader.
+ *
+ * This annotation reader is intended to be used in projects where you have
+ * full-control over all annotations that are available.
+ *
+ * @since  2.2
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class SimpleAnnotationReader implements Reader
+{
+    /**
+     * @var DocParser
+     */
+    private $parser;
+
+    /**
+     * Constructor.
+     *
+     * Initializes a new SimpleAnnotationReader.
+     */
+    public function __construct()
+    {
+        $this->parser = new DocParser();
+        $this->parser->setIgnoreNotImportedAnnotations(true);
+    }
+
+    /**
+     * Adds a namespace in which we will look for annotations.
+     *
+     * @param string $namespace
+     */
+    public function addNamespace($namespace)
+    {
+        $this->parser->addNamespace($namespace);
+    }
+
+    /**
+     * Gets the annotations applied to a class.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        return $this->parser->parse($class->getDocComment(), 'class '.$class->getName());
+    }
+
+     /**
+     * Gets the annotations applied to a method.
+     *
+     * @param ReflectionMethod $property The ReflectionMethod of the method from which
+     *                                   the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()');
+    }
+
+    /**
+     * Gets the annotations applied to a property.
+     *
+     * @param ReflectionProperty $property The ReflectionProperty of the property
+     *                                     from which the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName());
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        foreach ($this->getClassAnnotations($class) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        foreach ($this->getMethodAnnotations($method) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        foreach ($this->getPropertyAnnotations($property) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ApcCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ApcCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ApcCache.php	(revision 345)
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * APC cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class ApcCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return apc_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $found = false;
+
+        apc_fetch($id, $found);
+
+        return $found;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return (bool) apc_store($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return apc_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return apc_clear_cache() && apc_clear_cache('user');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = apc_cache_info();
+        $sma  = apc_sma_info();
+
+        return array(
+            Cache::STATS_HITS              => $info['num_hits'],
+            Cache::STATS_MISSES            => $info['num_misses'],
+            Cache::STATS_UPTIME            => $info['start_time'],
+            Cache::STATS_MEMORY_USAGE      => $info['mem_size'],
+            Cache::STATS_MEMORY_AVAILIABLE => $sma['avail_mem'],
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ArrayCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ArrayCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ArrayCache.php	(revision 345)
@@ -0,0 +1,96 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Array cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class ArrayCache extends CacheProvider
+{
+    /**
+     * @var array $data
+     */
+    private $data = array();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return (isset($this->data[$id])) ? $this->data[$id] : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return isset($this->data[$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $this->data[$id] = $data;
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        unset($this->data[$id]);
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->data = array();
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/Cache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/Cache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/Cache.php	(revision 345)
@@ -0,0 +1,102 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+interface Cache
+{
+    const STATS_HITS    = 'hits';
+    const STATS_MISSES  = 'misses';
+    const STATS_UPTIME  = 'uptime';
+    const STATS_MEMORY_USAGE        = 'memory_usage';
+    const STATS_MEMORY_AVAILIABLE   = 'memory_available';
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id cache id The id of the cache entry to fetch.
+     * @return string The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    function fetch($id);
+
+    /**
+     * Test if an entry exists in the cache.
+     *
+     * @param string $id cache id The cache id of the entry to check for.
+     * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    function contains($id);
+
+    /**
+     * Puts data into the cache.
+     *
+     * @param string $id The cache id.
+     * @param string $data The cache entry/data.
+     * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime).
+     * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    function save($id, $data, $lifeTime = 0);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id cache id
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    function delete($id);
+
+    /**
+     * Retrieves cached information from data store
+     *
+     * The server's statistics array has the following values:
+     *
+     * - <b>hits</b>
+     * Number of keys that have been requested and found present.
+     *
+     * - <b>misses</b>
+     * Number of items that have been requested and not found.
+     *
+     * - <b>uptime</b>
+     * Time that the server is running.
+     *
+     * - <b>memory_usage</b>
+     * Memory used by this server to store items.
+     *
+     * - <b>memory_available</b>
+     * Memory allowed to use for storage.
+     *
+     * @since   2.2
+     * @var     array Associative array with server's statistics if available, NULL otherwise.
+     */
+    function getStats();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/CacheProvider.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/CacheProvider.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/CacheProvider.php	(revision 345)
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Base class for cache provider implementations.
+ *
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+abstract class CacheProvider implements Cache
+{
+    const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
+
+    /**
+     * @var string The namespace to prefix all cache ids with
+     */
+    private $namespace = '';
+
+    /**
+     * Set the namespace to prefix all cache ids with.
+     *
+     * @param string $namespace
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace = (string) $namespace;
+    }
+
+    /**
+     * Retrieve the namespace that prefixes all cache ids.
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return $this->namespace;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($id)
+    {
+        return $this->doFetch($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function contains($id)
+    {
+        return $this->doContains($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function save($id, $data, $lifeTime = 0)
+    {
+        return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($id)
+    {
+        return $this->doDelete($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStats()
+    {
+        return $this->doGetStats();
+    }
+
+    /**
+     * Deletes all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise.
+     */
+    public function flushAll()
+    {
+        return $this->doFlush();
+    }
+
+    /**
+     * Delete all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise.
+     */
+    public function deleteAll()
+    {
+        $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+        $namespaceVersion  = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1;
+
+        return $this->doSave($namespaceCacheKey, $namespaceVersion + 1);
+    }
+
+    /**
+     * Prefix the passed id with the configured namespace value
+     *
+     * @param string $id  The id to namespace
+     * @return string $id The namespaced id
+     */
+    private function getNamespacedId($id)
+    {
+        $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+        $namespaceVersion  = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1;
+
+        return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
+    }
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id cache id The id of the cache entry to fetch.
+     * @return string The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    abstract protected function doFetch($id);
+
+    /**
+     * Test if an entry exists in the cache.
+     *
+     * @param string $id cache id The cache id of the entry to check for.
+     * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    abstract protected function doContains($id);
+
+    /**
+     * Puts data into the cache.
+     *
+     * @param string $id The cache id.
+     * @param string $data The cache entry/data.
+     * @param int $lifeTime The lifetime. If != false, sets a specific lifetime for this cache entry (null => infinite lifeTime).
+     * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    abstract protected function doSave($id, $data, $lifeTime = false);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id cache id
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doDelete($id);
+
+    /**
+     * Deletes all cache entries.
+     *
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doFlush();
+
+     /**
+     * Retrieves cached information from data store
+     *
+     * @since   2.2
+     * @return  array An associative array with server's statistics if available, NULL otherwise.
+     */
+    abstract protected function doGetStats();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcacheCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcacheCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcacheCache.php	(revision 345)
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcache;
+
+/**
+ * Memcache cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class MemcacheCache extends CacheProvider
+{
+    /**
+     * @var Memcache
+     */
+    private $memcache;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcache $memcache
+     */
+    public function setMemcache(Memcache $memcache)
+    {
+        $this->memcache = $memcache;
+    }
+
+    /**
+     * Gets the memcache instance used by the cache.
+     *
+     * @return Memcache
+     */
+    public function getMemcache()
+    {
+        return $this->memcache;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcache->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (bool) $this->memcache->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+        return $this->memcache->set($id, $data, 0, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->memcache->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcache->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats = $this->memcache->getStats();
+        return array(
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE       => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $stats['limit_maxbytes'],
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcachedCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcachedCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/MemcachedCache.php	(revision 345)
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcached;
+
+/**
+ * Memcached cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class MemcachedCache extends CacheProvider
+{
+    /**
+     * @var Memcached
+     */
+    private $memcached;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcached $memcached
+     */
+    public function setMemcached(Memcached $memcached)
+    {
+        $this->memcached = $memcached;
+    }
+
+    /**
+     * Gets the memcached instance used by the cache.
+     *
+     * @return Memcached
+     */
+    public function getMemcached()
+    {
+        return $this->memcached;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcached->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (false !== $this->memcached->get($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+        return $this->memcached->set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->memcached->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcached->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats   = $this->memcached->getStats();
+        $servers = $this->memcached->getServerList();
+        $key     = $servers[0]['host'] . ':' . $servers[0]['port'];
+        $stats   = $stats[$key];
+        return array(
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE       => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $stats['limit_maxbytes'],
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/WinCacheCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/WinCacheCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/WinCacheCache.php	(revision 345)
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * WinCache cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class WincacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return wincache_ucache_get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return wincache_ucache_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return (bool) wincache_ucache_set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return wincache_ucache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return wincache_ucache_clear();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info   = wincache_ucache_info();
+        $meminfo= wincache_ucache_meminfo();
+        return array(
+            Cache::STATS_HITS   => $info['total_hit_count'],
+            Cache::STATS_MISSES => $info['total_miss_count'],
+            Cache::STATS_UPTIME => $info['total_cache_uptime'],
+            Cache::STATS_MEMORY_USAGE       => $meminfo['memory_total'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $meminfo['memory_free'],
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/XcacheCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/XcacheCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/XcacheCache.php	(revision 345)
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Xcache cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class XcacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return xcache_isset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return xcache_set($id, serialize($data), (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return xcache_unset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->checkAuthorization();
+
+        xcache_clear_cache(XC_TYPE_VAR, 0);
+
+        return true;
+    }
+
+    /**
+     * Checks that xcache.admin.enable_auth is Off
+     *
+     * @throws \BadMethodCallException When xcache.admin.enable_auth is On
+     * @return void
+     */
+    protected function checkAuthorization()
+    {
+        if (ini_get('xcache.admin.enable_auth')) {
+            throw new \BadMethodCallException('To use all features of \Doctrine\Common\Cache\XcacheCache, you must set "xcache.admin.enable_auth" to "Off" in your php.ini.');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $this->checkAuthorization();
+
+        $info = xcache_info(XC_TYPE_VAR, 0);
+        return array(
+            Cache::STATS_HITS   => $info['hits'],
+            Cache::STATS_MISSES => $info['misses'],
+            Cache::STATS_UPTIME => null,
+            Cache::STATS_MEMORY_USAGE       => $info['size'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $info['avail'],
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ZendDataCache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ZendDataCache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Cache/ZendDataCache.php	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Zend Data Cache cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Ralph Schindler <ralph.schindler@zend.com>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class ZendDataCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return zend_shm_cache_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (false !== zend_shm_cache_fetch($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return zend_shm_cache_store($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return zend_shm_cache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $namespace = $this->getNamespace();
+        if (empty($namespace)) {
+            return zend_shm_cache_clear();
+        }
+        return zend_shm_cache_clear($namespace);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/ClassLoader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/ClassLoader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/ClassLoader.php	(revision 345)
@@ -0,0 +1,262 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * A <tt>ClassLoader</tt> is an autoloader for class files that can be
+ * installed on the SPL autoload stack. It is a class loader that either loads only classes
+ * of a specific namespace or all namespaces and it is suitable for working together
+ * with other autoloaders in the SPL autoload stack.
+ *
+ * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
+ * relies on the PHP <code>include_path</code>.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class ClassLoader
+{
+    /**
+     * @var string PHP file extension
+     */
+    protected $fileExtension = '.php';
+
+    /**
+     * @var string Current namespace
+     */
+    protected $namespace;
+
+    /**
+     * @var string Current include path
+     */
+    protected $includePath;
+
+    /**
+     * @var string PHP namespace separator
+     */
+    protected $namespaceSeparator = '\\';
+
+    /**
+     * Creates a new <tt>ClassLoader</tt> that loads classes of the
+     * specified namespace from the specified include path.
+     *
+     * If no include path is given, the ClassLoader relies on the PHP include_path.
+     * If neither a namespace nor an include path is given, the ClassLoader will
+     * be responsible for loading all classes, thereby relying on the PHP include_path.
+     *
+     * @param string $ns The namespace of the classes to load.
+     * @param string $includePath The base include path to use.
+     */
+    public function __construct($ns = null, $includePath = null)
+    {
+        $this->namespace = $ns;
+        $this->includePath = $includePath;
+    }
+
+    /**
+     * Sets the namespace separator used by classes in the namespace of this ClassLoader.
+     *
+     * @param string $sep The separator to use.
+     */
+    public function setNamespaceSeparator($sep)
+    {
+        $this->namespaceSeparator = $sep;
+    }
+
+    /**
+     * Gets the namespace separator used by classes in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getNamespaceSeparator()
+    {
+        return $this->namespaceSeparator;
+    }
+
+    /**
+     * Sets the base include path for all class files in the namespace of this ClassLoader.
+     *
+     * @param string $includePath
+     */
+    public function setIncludePath($includePath)
+    {
+        $this->includePath = $includePath;
+    }
+
+    /**
+     * Gets the base include path for all class files in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getIncludePath()
+    {
+        return $this->includePath;
+    }
+
+    /**
+     * Sets the file extension of class files in the namespace of this ClassLoader.
+     *
+     * @param string $fileExtension
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Gets the file extension of class files in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Registers this ClassLoader on the SPL autoload stack.
+     */
+    public function register()
+    {
+        spl_autoload_register(array($this, 'loadClass'));
+    }
+
+    /**
+     * Removes this ClassLoader from the SPL autoload stack.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param string $classname The name of the class to load.
+     * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
+     */
+    public function loadClass($className)
+    {
+        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
+            return false;
+        }
+
+        require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
+               . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
+               . $this->fileExtension;
+
+        return true;
+    }
+
+    /**
+     * Asks this ClassLoader whether it can potentially load the class (file) with
+     * the given name.
+     *
+     * @param string $className The fully-qualified name of the class.
+     * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise.
+     */
+    public function canLoadClass($className)
+    {
+        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
+            return false;
+        }
+
+        $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
+
+        if ($this->includePath !== null) {
+            return file_exists($this->includePath . DIRECTORY_SEPARATOR . $file);
+        }
+
+        return (false !== stream_resolve_include_path($file));
+    }
+
+    /**
+     * Checks whether a class with a given name exists. A class "exists" if it is either
+     * already defined in the current request or if there is an autoloader on the SPL
+     * autoload stack that is a) responsible for the class in question and b) is able to
+     * load a class file in which the class definition resides.
+     *
+     * If the class is not already defined, each autoloader in the SPL autoload stack
+     * is asked whether it is able to tell if the class exists. If the autoloader is
+     * a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
+     * function of the autoloader is invoked and expected to return a value that
+     * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
+     * that the class exists, TRUE is returned.
+     *
+     * Note that, depending on what kinds of autoloaders are installed on the SPL
+     * autoload stack, the class (file) might already be loaded as a result of checking
+     * for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
+     * these responsibilities.
+     *
+     * @param string $className The fully-qualified name of the class.
+     * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise.
+     */
+    public static function classExists($className)
+    {
+        if (class_exists($className, false) || interface_exists($className, false)) {
+            return true;
+        }
+
+        foreach (spl_autoload_functions() as $loader) {
+            if (is_array($loader)) { // array(???, ???)
+                if (is_object($loader[0])) {
+                    if ($loader[0] instanceof ClassLoader) { // array($obj, 'methodName')
+                        if ($loader[0]->canLoadClass($className)) {
+                            return true;
+                        }
+                    } else if ($loader[0]->{$loader[1]}($className)) {
+                        return true;
+                    }
+                } else if ($loader[0]::$loader[1]($className)) { // array('ClassName', 'methodName')
+                    return true;
+                }
+            } else if ($loader instanceof \Closure) { // function($className) {..}
+                if ($loader($className)) {
+                    return true;
+                }
+            } else if (is_string($loader) && $loader($className)) { // "MyClass::loadClass"
+                return true;
+            }
+        }
+
+        return class_exists($className, false) || interface_exists($className, false);
+    }
+
+    /**
+     * Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
+     * for (and is able to load) the class with the given name.
+     *
+     * @param string $className The name of the class.
+     * @return The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
+     */
+    public static function getClassLoader($className)
+    {
+         foreach (spl_autoload_functions() as $loader) {
+            if (is_array($loader)
+                && $loader[0] instanceof ClassLoader
+                && $loader[0]->canLoadClass($className)
+            ) {
+                return $loader[0];
+            }
+        }
+
+        return null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/ArrayCollection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/ArrayCollection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/ArrayCollection.php	(revision 345)
@@ -0,0 +1,447 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Collections;
+
+use Closure, ArrayIterator;
+
+/**
+ * An ArrayCollection is a Collection implementation that wraps a regular PHP array.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ArrayCollection implements Collection
+{
+    /**
+     * An array containing the entries of this collection.
+     *
+     * @var array
+     */
+    private $_elements;
+
+    /**
+     * Initializes a new ArrayCollection.
+     *
+     * @param array $elements
+     */
+    public function __construct(array $elements = array())
+    {
+        $this->_elements = $elements;
+    }
+
+    /**
+     * Gets the PHP array representation of this collection.
+     *
+     * @return array The PHP array representation of this collection.
+     */
+    public function toArray()
+    {
+        return $this->_elements;
+    }
+
+    /**
+     * Sets the internal iterator to the first element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    public function first()
+    {
+        return reset($this->_elements);
+    }
+
+    /**
+     * Sets the internal iterator to the last element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    public function last()
+    {
+        return end($this->_elements);
+    }
+
+    /**
+     * Gets the current key/index at the current internal iterator position.
+     *
+     * @return mixed
+     */
+    public function key()
+    {
+        return key($this->_elements);
+    }
+
+    /**
+     * Moves the internal iterator position to the next element.
+     *
+     * @return mixed
+     */
+    public function next()
+    {
+        return next($this->_elements);
+    }
+
+    /**
+     * Gets the element of the collection at the current internal iterator position.
+     *
+     * @return mixed
+     */
+    public function current()
+    {
+        return current($this->_elements);
+    }
+
+    /**
+     * Removes an element with a specific key/index from the collection.
+     *
+     * @param mixed $key
+     * @return mixed The removed element or NULL, if no element exists for the given key.
+     */
+    public function remove($key)
+    {
+        if (isset($this->_elements[$key])) {
+            $removed = $this->_elements[$key];
+            unset($this->_elements[$key]);
+
+            return $removed;
+        }
+
+        return null;
+    }
+
+    /**
+     * Removes the specified element from the collection, if it is found.
+     *
+     * @param mixed $element The element to remove.
+     * @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
+     */
+    public function removeElement($element)
+    {
+        $key = array_search($element, $this->_elements, true);
+
+        if ($key !== false) {
+            unset($this->_elements[$key]);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * ArrayAccess implementation of offsetExists()
+     *
+     * @see containsKey()
+     */
+    public function offsetExists($offset)
+    {
+        return $this->containsKey($offset);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetGet()
+     *
+     * @see get()
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetGet()
+     *
+     * @see add()
+     * @see set()
+     */
+    public function offsetSet($offset, $value)
+    {
+        if ( ! isset($offset)) {
+            return $this->add($value);
+        }
+        return $this->set($offset, $value);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetUnset()
+     *
+     * @see remove()
+     */
+    public function offsetUnset($offset)
+    {
+        return $this->remove($offset);
+    }
+
+    /**
+     * Checks whether the collection contains a specific key/index.
+     *
+     * @param mixed $key The key to check for.
+     * @return boolean TRUE if the given key/index exists, FALSE otherwise.
+     */
+    public function containsKey($key)
+    {
+        return isset($this->_elements[$key]);
+    }
+
+    /**
+     * Checks whether the given element is contained in the collection.
+     * Only element values are compared, not keys. The comparison of two elements
+     * is strict, that means not only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element
+     * @return boolean TRUE if the given element is contained in the collection,
+     *          FALSE otherwise.
+     */
+    public function contains($element)
+    {
+        foreach ($this->_elements as $collectionElement) {
+            if ($element === $collectionElement) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Tests for the existance of an element that satisfies the given predicate.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
+     */
+    public function exists(Closure $p)
+    {
+        foreach ($this->_elements as $key => $element) {
+            if ($p($key, $element)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Searches for a given element and, if found, returns the corresponding key/index
+     * of that element. The comparison of two elements is strict, that means not
+     * only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element The element to search for.
+     * @return mixed The key/index of the element or FALSE if the element was not found.
+     */
+    public function indexOf($element)
+    {
+        return array_search($element, $this->_elements, true);
+    }
+
+    /**
+     * Gets the element with the given key/index.
+     *
+     * @param mixed $key The key.
+     * @return mixed The element or NULL, if no element exists for the given key.
+     */
+    public function get($key)
+    {
+        if (isset($this->_elements[$key])) {
+            return $this->_elements[$key];
+        }
+        return null;
+    }
+
+    /**
+     * Gets all keys/indexes of the collection elements.
+     *
+     * @return array
+     */
+    public function getKeys()
+    {
+        return array_keys($this->_elements);
+    }
+
+    /**
+     * Gets all elements.
+     *
+     * @return array
+     */
+    public function getValues()
+    {
+        return array_values($this->_elements);
+    }
+
+    /**
+     * Returns the number of elements in the collection.
+     *
+     * Implementation of the Countable interface.
+     *
+     * @return integer The number of elements in the collection.
+     */
+    public function count()
+    {
+        return count($this->_elements);
+    }
+
+    /**
+     * Adds/sets an element in the collection at the index / with the specified key.
+     *
+     * When the collection is a Map this is like put(key,value)/add(key,value).
+     * When the collection is a List this is like add(position,value).
+     *
+     * @param mixed $key
+     * @param mixed $value
+     */
+    public function set($key, $value)
+    {
+        $this->_elements[$key] = $value;
+    }
+
+    /**
+     * Adds an element to the collection.
+     *
+     * @param mixed $value
+     * @return boolean Always TRUE.
+     */
+    public function add($value)
+    {
+        $this->_elements[] = $value;
+        return true;
+    }
+
+    /**
+     * Checks whether the collection is empty.
+     *
+     * Note: This is preferrable over count() == 0.
+     *
+     * @return boolean TRUE if the collection is empty, FALSE otherwise.
+     */
+    public function isEmpty()
+    {
+        return ! $this->_elements;
+    }
+
+    /**
+     * Gets an iterator for iterating over the elements in the collection.
+     *
+     * @return ArrayIterator
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->_elements);
+    }
+
+    /**
+     * Applies the given function to each element in the collection and returns
+     * a new collection with the elements returned by the function.
+     *
+     * @param Closure $func
+     * @return Collection
+     */
+    public function map(Closure $func)
+    {
+        return new static(array_map($func, $this->_elements));
+    }
+
+    /**
+     * Returns all the elements of this collection that satisfy the predicate p.
+     * The order of the elements is preserved.
+     *
+     * @param Closure $p The predicate used for filtering.
+     * @return Collection A collection with the results of the filter operation.
+     */
+    public function filter(Closure $p)
+    {
+        return new static(array_filter($this->_elements, $p));
+    }
+
+    /**
+     * Applies the given predicate p to all elements of this collection,
+     * returning true, if the predicate yields true for all elements.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
+     */
+    public function forAll(Closure $p)
+    {
+        foreach ($this->_elements as $key => $element) {
+            if ( ! $p($key, $element)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Partitions this collection in two collections according to a predicate.
+     * Keys are preserved in the resulting collections.
+     *
+     * @param Closure $p The predicate on which to partition.
+     * @return array An array with two elements. The first element contains the collection
+     *               of elements where the predicate returned TRUE, the second element
+     *               contains the collection of elements where the predicate returned FALSE.
+     */
+    public function partition(Closure $p)
+    {
+        $coll1 = $coll2 = array();
+        foreach ($this->_elements as $key => $element) {
+            if ($p($key, $element)) {
+                $coll1[$key] = $element;
+            } else {
+                $coll2[$key] = $element;
+            }
+        }
+        return array(new static($coll1), new static($coll2));
+    }
+
+    /**
+     * Returns a string representation of this object.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return __CLASS__ . '@' . spl_object_hash($this);
+    }
+
+    /**
+     * Clears the collection.
+     */
+    public function clear()
+    {
+        $this->_elements = array();
+    }
+
+    /**
+     * Extract a slice of $length elements starting at position $offset from the Collection.
+     *
+     * If $length is null it returns all elements from $offset to the end of the Collection.
+     * Keys have to be preserved by this method. Calling this method will only return the
+     * selected slice and NOT change the elements contained in the collection slice is called on.
+     *
+     * @param int $offset
+     * @param int $length
+     * @return array
+     */
+    public function slice($offset, $length = null)
+    {
+        return array_slice($this->_elements, $offset, $length, true);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/Collection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/Collection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Collections/Collection.php	(revision 345)
@@ -0,0 +1,243 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Collections;
+
+use Closure, Countable, IteratorAggregate, ArrayAccess;
+
+/**
+ * The missing (SPL) Collection/Array/OrderedMap interface.
+ *
+ * A Collection resembles the nature of a regular PHP array. That is,
+ * it is essentially an <b>ordered map</b> that can also be used
+ * like a list.
+ *
+ * A Collection has an internal iterator just like a PHP array. In addition,
+ * a Collection can be iterated with external iterators, which is preferrable.
+ * To use an external iterator simply use the foreach language construct to
+ * iterate over the collection (which calls {@link getIterator()} internally) or
+ * explicitly retrieve an iterator though {@link getIterator()} which can then be
+ * used to iterate over the collection.
+ * You can not rely on the internal iterator of the collection being at a certain
+ * position unless you explicitly positioned it before. Prefer iteration with
+ * external iterators.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface Collection extends Countable, IteratorAggregate, ArrayAccess
+{
+    /**
+     * Adds an element at the end of the collection.
+     *
+     * @param mixed $element The element to add.
+     * @return boolean Always TRUE.
+     */
+    function add($element);
+
+    /**
+     * Clears the collection, removing all elements.
+     */
+    function clear();
+
+    /**
+     * Checks whether an element is contained in the collection.
+     * This is an O(n) operation, where n is the size of the collection.
+     *
+     * @param mixed $element The element to search for.
+     * @return boolean TRUE if the collection contains the element, FALSE otherwise.
+     */
+    function contains($element);
+
+    /**
+     * Checks whether the collection is empty (contains no elements).
+     *
+     * @return boolean TRUE if the collection is empty, FALSE otherwise.
+     */
+    function isEmpty();
+
+    /**
+     * Removes the element at the specified index from the collection.
+     *
+     * @param string|integer $key The kex/index of the element to remove.
+     * @return mixed The removed element or NULL, if the collection did not contain the element.
+     */
+    function remove($key);
+
+    /**
+     * Removes the specified element from the collection, if it is found.
+     *
+     * @param mixed $element The element to remove.
+     * @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
+     */
+    function removeElement($element);
+
+    /**
+     * Checks whether the collection contains an element with the specified key/index.
+     *
+     * @param string|integer $key The key/index to check for.
+     * @return boolean TRUE if the collection contains an element with the specified key/index,
+     *          FALSE otherwise.
+     */
+    function containsKey($key);
+
+    /**
+     * Gets the element at the specified key/index.
+     *
+     * @param string|integer $key The key/index of the element to retrieve.
+     * @return mixed
+     */
+    function get($key);
+
+    /**
+     * Gets all keys/indices of the collection.
+     *
+     * @return array The keys/indices of the collection, in the order of the corresponding
+     *          elements in the collection.
+     */
+    function getKeys();
+
+    /**
+     * Gets all values of the collection.
+     *
+     * @return array The values of all elements in the collection, in the order they
+     *          appear in the collection.
+     */
+    function getValues();
+
+    /**
+     * Sets an element in the collection at the specified key/index.
+     *
+     * @param string|integer $key The key/index of the element to set.
+     * @param mixed $value The element to set.
+     */
+    function set($key, $value);
+
+    /**
+     * Gets a native PHP array representation of the collection.
+     *
+     * @return array
+     */
+    function toArray();
+
+    /**
+     * Sets the internal iterator to the first element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    function first();
+
+    /**
+     * Sets the internal iterator to the last element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    function last();
+
+    /**
+     * Gets the key/index of the element at the current iterator position.
+     *
+     */
+    function key();
+
+    /**
+     * Gets the element of the collection at the current iterator position.
+     *
+     */
+    function current();
+
+    /**
+     * Moves the internal iterator position to the next element.
+     *
+     */
+    function next();
+
+    /**
+     * Tests for the existence of an element that satisfies the given predicate.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
+     */
+    function exists(Closure $p);
+
+    /**
+     * Returns all the elements of this collection that satisfy the predicate p.
+     * The order of the elements is preserved.
+     *
+     * @param Closure $p The predicate used for filtering.
+     * @return Collection A collection with the results of the filter operation.
+     */
+    function filter(Closure $p);
+
+    /**
+     * Applies the given predicate p to all elements of this collection,
+     * returning true, if the predicate yields true for all elements.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
+     */
+    function forAll(Closure $p);
+
+    /**
+     * Applies the given function to each element in the collection and returns
+     * a new collection with the elements returned by the function.
+     *
+     * @param Closure $func
+     * @return Collection
+     */
+    function map(Closure $func);
+
+    /**
+     * Partitions this collection in two collections according to a predicate.
+     * Keys are preserved in the resulting collections.
+     *
+     * @param Closure $p The predicate on which to partition.
+     * @return array An array with two elements. The first element contains the collection
+     *               of elements where the predicate returned TRUE, the second element
+     *               contains the collection of elements where the predicate returned FALSE.
+     */
+    function partition(Closure $p);
+
+    /**
+     * Gets the index/key of a given element. The comparison of two elements is strict,
+     * that means not only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element The element to search for.
+     * @return mixed The key/index of the element or FALSE if the element was not found.
+     */
+    function indexOf($element);
+
+    /**
+     * Extract a slice of $length elements starting at position $offset from the Collection.
+     *
+     * If $length is null it returns all elements from $offset to the end of the Collection.
+     * Keys have to be preserved by this method. Calling this method will only return the
+     * selected slice and NOT change the elements contained in the collection slice is called on.
+     *
+     * @param int $offset
+     * @param int $length
+     * @return array
+     */
+    function slice($offset, $length = null);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/CommonException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/CommonException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/CommonException.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Base exception class for package Doctrine\Common
+ * @author heinrich
+ *
+ */
+class CommonException extends \Exception {
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Comparable.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Comparable.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Comparable.php	(revision 345)
@@ -0,0 +1,47 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\Common;
+
+/**
+ * Comparable interface that allows to compare two value objects to each other for similarity.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+interface Comparable
+{
+    /**
+     * Compare the current object to the passed $other.
+     *
+     * Returns 0 if they are semantically equal, 1 if the other object
+     * is less than the current one, or -1 if its more than the current one.
+     *
+     * This method should not check for identity using ===, only for semantical equality for example
+     * when two different DateTime instances point to the exact same Date + TZ.
+     *
+     * @return int
+     */
+    public function compareTo($other);
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventArgs.php	(revision 345)
@@ -0,0 +1,69 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * EventArgs is the base class for classes containing event data.
+ *
+ * This class contains no event data. It is used by events that do not pass state
+ * information to an event handler when an event is raised. The single empty EventArgs
+ * instance can be obtained through {@link getEmptyInstance}.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EventArgs
+{
+    /**
+     * @var EventArgs Single instance of EventArgs
+     * @static
+     */
+    private static $_emptyEventArgsInstance;
+
+    /**
+     * Gets the single, empty and immutable EventArgs instance.
+     *
+     * This instance will be used when events are dispatched without any parameter,
+     * like this: EventManager::dispatchEvent('eventname');
+     *
+     * The benefit from this is that only one empty instance is instantiated and shared
+     * (otherwise there would be instances for every dispatched in the abovementioned form)
+     *
+     * @see EventManager::dispatchEvent
+     * @link http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
+     * @static
+     * @return EventArgs
+     */
+    public static function getEmptyInstance()
+    {
+        if ( ! self::$_emptyEventArgsInstance) {
+            self::$_emptyEventArgsInstance = new EventArgs;
+        }
+
+        return self::$_emptyEventArgsInstance;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventManager.php	(revision 345)
@@ -0,0 +1,136 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * The EventManager is the central point of Doctrine's event listener system.
+ * Listeners are registered on the manager and events are dispatched through the
+ * manager.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EventManager
+{
+    /**
+     * Map of registered listeners.
+     * <event> => <listeners>
+     *
+     * @var array
+     */
+    private $_listeners = array();
+
+    /**
+     * Dispatches an event to all registered listeners.
+     *
+     * @param string $eventName The name of the event to dispatch. The name of the event is
+     *                          the name of the method that is invoked on listeners.
+     * @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
+     *                             If not supplied, the single empty EventArgs instance is used.
+     * @return boolean
+     */
+    public function dispatchEvent($eventName, EventArgs $eventArgs = null)
+    {
+        if (isset($this->_listeners[$eventName])) {
+            $eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs;
+
+            foreach ($this->_listeners[$eventName] as $listener) {
+                $listener->$eventName($eventArgs);
+            }
+        }
+    }
+
+    /**
+     * Gets the listeners of a specific event or all listeners.
+     *
+     * @param string $event The name of the event.
+     * @return array The event listeners for the specified event, or all event listeners.
+     */
+    public function getListeners($event = null)
+    {
+        return $event ? $this->_listeners[$event] : $this->_listeners;
+    }
+
+    /**
+     * Checks whether an event has any registered listeners.
+     *
+     * @param string $event
+     * @return boolean TRUE if the specified event has any listeners, FALSE otherwise.
+     */
+    public function hasListeners($event)
+    {
+        return isset($this->_listeners[$event]) && $this->_listeners[$event];
+    }
+
+    /**
+     * Adds an event listener that listens on the specified events.
+     *
+     * @param string|array $events The event(s) to listen on.
+     * @param object $listener The listener object.
+     */
+    public function addEventListener($events, $listener)
+    {
+        // Picks the hash code related to that listener
+        $hash = spl_object_hash($listener);
+
+        foreach ((array) $events as $event) {
+            // Overrides listener if a previous one was associated already
+            // Prevents duplicate listeners on same event (same instance only)
+            $this->_listeners[$event][$hash] = $listener;
+        }
+    }
+
+    /**
+     * Removes an event listener from the specified events.
+     *
+     * @param string|array $events
+     * @param object $listener
+     */
+    public function removeEventListener($events, $listener)
+    {
+        // Picks the hash code related to that listener
+        $hash = spl_object_hash($listener);
+
+        foreach ((array) $events as $event) {
+            // Check if actually have this listener associated
+            if (isset($this->_listeners[$event][$hash])) {
+                unset($this->_listeners[$event][$hash]);
+            }
+        }
+    }
+
+    /**
+     * Adds an EventSubscriber. The subscriber is asked for all the events he is
+     * interested in and added as a listener for these events.
+     *
+     * @param Doctrine\Common\EventSubscriber $subscriber The subscriber.
+     */
+    public function addEventSubscriber(EventSubscriber $subscriber)
+    {
+        $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventSubscriber.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventSubscriber.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/EventSubscriber.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ *  $Id: EventListener.php 4653 2008-07-10 17:17:58Z romanb $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * An EventSubscriber knows himself what events he is interested in.
+ * If an EventSubscriber is added to an EventManager, the manager invokes
+ * {@link getSubscribedEvents} and registers the subscriber as a listener for all
+ * returned events.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface EventSubscriber
+{
+    /**
+     * Returns an array of events this subscriber wants to listen to.
+     *
+     * @return array
+     */
+    function getSubscribedEvents();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Lexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Lexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Lexer.php	(revision 345)
@@ -0,0 +1,266 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Base class for writing simple lexers, i.e. for creating small DSLs.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @todo Rename: AbstractLexer
+ */
+abstract class Lexer
+{
+    /**
+     * @var array Array of scanned tokens
+     */
+    private $tokens = array();
+
+    /**
+     * @var integer Current lexer position in input string
+     */
+    private $position = 0;
+
+    /**
+     * @var integer Current peek of current lexer position
+     */
+    private $peek = 0;
+
+    /**
+     * @var array The next token in the input.
+     */
+    public $lookahead;
+
+    /**
+     * @var array The last matched/seen token.
+     */
+    public $token;
+
+    /**
+     * Sets the input data to be tokenized.
+     *
+     * The Lexer is immediately reset and the new input tokenized.
+     * Any unprocessed tokens from any previous input are lost.
+     *
+     * @param string $input The input to be tokenized.
+     */
+    public function setInput($input)
+    {
+        $this->tokens = array();
+        $this->reset();
+        $this->scan($input);
+    }
+
+    /**
+     * Resets the lexer.
+     */
+    public function reset()
+    {
+        $this->lookahead = null;
+        $this->token = null;
+        $this->peek = 0;
+        $this->position = 0;
+    }
+
+    /**
+     * Resets the peek pointer to 0.
+     */
+    public function resetPeek()
+    {
+        $this->peek = 0;
+    }
+
+    /**
+     * Resets the lexer position on the input to the given position.
+     *
+     * @param integer $position Position to place the lexical scanner
+     */
+    public function resetPosition($position = 0)
+    {
+        $this->position = $position;
+    }
+
+    /**
+     * Checks whether a given token matches the current lookahead.
+     *
+     * @param integer|string $token
+     * @return boolean
+     */
+    public function isNextToken($token)
+    {
+        return null !== $this->lookahead && $this->lookahead['type'] === $token;
+    }
+
+    /**
+     * Checks whether any of the given tokens matches the current lookahead
+     *
+     * @param array $tokens
+     * @return boolean
+     */
+    public function isNextTokenAny(array $tokens)
+    {
+        return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true);
+    }
+
+    /**
+     * Moves to the next token in the input string.
+     *
+     * A token is an associative array containing three items:
+     *  - 'value'    : the string value of the token in the input string
+     *  - 'type'     : the type of the token (identifier, numeric, string, input
+     *                 parameter, none)
+     *  - 'position' : the position of the token in the input string
+     *
+     * @return array|null the next token; null if there is no more tokens left
+     */
+    public function moveNext()
+    {
+        $this->peek = 0;
+        $this->token = $this->lookahead;
+        $this->lookahead = (isset($this->tokens[$this->position]))
+            ? $this->tokens[$this->position++] : null;
+
+        return $this->lookahead !== null;
+    }
+
+    /**
+     * Tells the lexer to skip input tokens until it sees a token with the given value.
+     *
+     * @param $type The token type to skip until.
+     */
+    public function skipUntil($type)
+    {
+        while ($this->lookahead !== null && $this->lookahead['type'] !== $type) {
+            $this->moveNext();
+        }
+    }
+
+    /**
+     * Checks if given value is identical to the given token
+     *
+     * @param mixed $value
+     * @param integer $token
+     * @return boolean
+     */
+    public function isA($value, $token)
+    {
+        return $this->getType($value) === $token;
+    }
+
+    /**
+     * Moves the lookahead token forward.
+     *
+     * @return array | null The next token or NULL if there are no more tokens ahead.
+     */
+    public function peek()
+    {
+        if (isset($this->tokens[$this->position + $this->peek])) {
+            return $this->tokens[$this->position + $this->peek++];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Peeks at the next token, returns it and immediately resets the peek.
+     *
+     * @return array|null The next token or NULL if there are no more tokens ahead.
+     */
+    public function glimpse()
+    {
+        $peek = $this->peek();
+        $this->peek = 0;
+        return $peek;
+    }
+
+    /**
+     * Scans the input string for tokens.
+     *
+     * @param string $input a query string
+     */
+    protected function scan($input)
+    {
+        static $regex;
+
+        if ( ! isset($regex)) {
+            $regex = '/(' . implode(')|(', $this->getCatchablePatterns()) . ')|'
+                   . implode('|', $this->getNonCatchablePatterns()) . '/i';
+        }
+
+        $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
+        $matches = preg_split($regex, $input, -1, $flags);
+
+        foreach ($matches as $match) {
+            // Must remain before 'value' assignment since it can change content
+            $type = $this->getType($match[0]);
+
+            $this->tokens[] = array(
+                'value' => $match[0],
+                'type'  => $type,
+                'position' => $match[1],
+            );
+        }
+    }
+
+    /**
+     * Gets the literal for a given token.
+     *
+     * @param integer $token
+     * @return string
+     */
+    public function getLiteral($token)
+    {
+        $className = get_class($this);
+        $reflClass = new \ReflectionClass($className);
+        $constants = $reflClass->getConstants();
+
+        foreach ($constants as $name => $value) {
+            if ($value === $token) {
+                return $className . '::' . $name;
+            }
+        }
+
+        return $token;
+    }
+
+    /**
+     * Lexical catchable patterns.
+     *
+     * @return array
+     */
+    abstract protected function getCatchablePatterns();
+
+    /**
+     * Lexical non-catchable patterns.
+     *
+     * @return array
+     */
+    abstract protected function getNonCatchablePatterns();
+
+    /**
+     * Retrieve token type. Also processes the token value if necessary.
+     *
+     * @param string $value
+     * @return integer
+     */
+    abstract protected function getType(&$value);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/NotifyPropertyChanged.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/NotifyPropertyChanged.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/NotifyPropertyChanged.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Contract for classes that provide the service of notifying listeners of
+ * changes to their properties.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface NotifyPropertyChanged
+{
+    /**
+     * Adds a listener that wants to be notified about property changes.
+     *
+     * @param PropertyChangedListener $listener
+     */
+    function addPropertyChangedListener(PropertyChangedListener $listener);
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/AbstractManagerRegistry.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/AbstractManagerRegistry.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/AbstractManagerRegistry.php	(revision 345)
@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\ManagerRegistry;
+
+/**
+ * Abstract implementation of the ManagerRegistry contract.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+abstract class AbstractManagerRegistry implements ManagerRegistry
+{
+    private $name;
+    private $connections;
+    private $managers;
+    private $defaultConnection;
+    private $defaultManager;
+    private $proxyInterfaceName;
+
+    public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName)
+    {
+        $this->name = $name;
+        $this->connections = $connections;
+        $this->managers = $managers;
+        $this->defaultConnection = $defaultConnection;
+        $this->defaultManager = $defaultManager;
+        $this->proxyInterfaceName = $proxyInterfaceName;
+    }
+
+    /**
+     * Fetches/creates the given services
+     *
+     * A service in this context is connection or a manager instance
+     *
+     * @param string $name name of the service
+     * @return object instance of the given service
+     */
+    abstract protected function getService($name);
+
+    /**
+     * Resets the given services
+     *
+     * A service in this context is connection or a manager instance
+     *
+     * @param string $name name of the service
+     * @return void
+     */
+    abstract protected function resetService($name);
+
+    /**
+     * Get the name of the registry
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnection($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultConnection;
+        }
+
+        if (!isset($this->connections[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name));
+        }
+
+        return $this->getService($this->connections[$name]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnectionNames()
+    {
+        return $this->connections;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnections()
+    {
+        $connections = array();
+        foreach ($this->connections as $name => $id) {
+            $connections[$name] = $this->getService($id);
+        }
+
+        return $connections;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getDefaultConnectionName()
+    {
+        return $this->defaultConnection;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getDefaultManagerName()
+    {
+        return $this->defaultManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManager($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultManager;
+        }
+
+        if (!isset($this->managers[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+        }
+
+        return $this->getService($this->managers[$name]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagerForClass($class)
+    {
+        $proxyClass = new \ReflectionClass($class);
+        if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
+            $class = $proxyClass->getParentClass()->getName();
+        }
+
+        foreach ($this->managers as $id) {
+            $manager = $this->getService($id);
+
+            if (!$manager->getMetadataFactory()->isTransient($class)) {
+                return $manager;
+            }
+        }
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagerNames()
+    {
+        return $this->managers;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagers()
+    {
+        $dms = array();
+        foreach ($this->managers as $name => $id) {
+            $dms[$name] = $this->getService($id);
+        }
+
+        return $dms;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getRepository($persistentObjectName, $persistentManagerName = null)
+    {
+        return $this->getManager($persistentManagerName)->getRepository($persistentObjectName);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function resetManager($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultManager;
+        }
+
+        if (!isset($this->managers[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+        }
+
+        // force the creation of a new document manager
+        // if the current one is closed
+        $this->resetService($this->managers[$name]);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ConnectionRegistry.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ConnectionRegistry.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ConnectionRegistry.php	(revision 345)
@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+interface ConnectionRegistry
+{
+    /**
+     * Gets the default connection name.
+     *
+     * @return string The default connection name
+     */
+    function getDefaultConnectionName();
+
+    /**
+     * Gets the named connection.
+     *
+     * @param string $name The connection name (null for the default one)
+     *
+     * @return Connection
+     */
+    function getConnection($name = null);
+
+    /**
+     * Gets an array of all registered connections
+     *
+     * @return array An array of Connection instances
+     */
+    function getConnections();
+
+    /**
+     * Gets all connection names.
+     *
+     * @return array An array of connection names
+     */
+    function getConnectionNames();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php	(revision 345)
@@ -0,0 +1,77 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
+ * of entities.
+ *
+ * @link   www.doctrine-project.org
+ * @since  2.2
+ * @author Roman Borschel <roman@code-factory.de>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LifecycleEventArgs extends EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var object
+     */
+    private $entity;
+
+    /**
+     * Constructor
+     *
+     * @param object $entity
+     * @param ObjectManager $objectManager
+     */
+    public function __construct($entity, ObjectManager $objectManager)
+    {
+        $this->entity = $entity;
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retireve associated Entity.
+     *
+     * @return object
+     */
+    public function getEntity()
+    {
+        return $this->entity;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\Common\Persistence\ObjectManager;
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Class that holds event arguments for a loadMetadata event.
+ *
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @since  2.2
+ */
+class LoadClassMetadataEventArgs extends EventArgs
+{
+    /**
+     * @var ClassMetadata
+     */
+    private $classMetadata;
+
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Constructor.
+     *
+     * @param ClasseMetadata $classMetadata
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager)
+    {
+        $this->classMetadata = $classMetadata;
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retrieve associated ClassMetadata.
+     *
+     * @return ClassMetadata
+     */
+    public function getClassMetadata()
+    {
+        return $this->classMetadata;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/ManagerEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/ManagerEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/ManagerEventArgs.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Provides event arguments for the preFlush event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.2
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ManagerEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Constructor.
+     *
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ObjectManager $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/OnClearEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/OnClearEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/OnClearEventArgs.php	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+/**
+ * Provides event arguments for the onClear event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.2
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OnClearEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var string
+     */
+    private $entityClass;
+
+    /**
+     * Constructor.
+     *
+     * @param ObjectManager $objectManager
+     * @param string $entityClass Optional entity class
+     */
+    public function __construct($objectManager, $entityClass = null)
+    {
+        $this->objectManager = $objectManager;
+        $this->entityClass = $entityClass;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+
+    /**
+     * Name of the entity class that is cleared, or empty if all are cleared.
+     *
+     * @return string
+     */
+    public function getEntityClass()
+    {
+        return $this->entityClass;
+    }
+
+    /**
+     * Check if event clears all entities.
+     *
+     * @return bool
+     */
+    public function clearsAllEntities()
+    {
+        return ($this->entityClass === null);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php	(revision 345)
@@ -0,0 +1,129 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs,
+    Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Class that holds event arguments for a preUpdate event.
+ *
+ * @author Guilherme Blanco <guilehrmeblanco@hotmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since  2.2
+ */
+class PreUpdateEventArgs extends LifecycleEventArgs
+{
+    /**
+     * @var array
+     */
+    private $entityChangeSet;
+
+    /**
+     * Constructor.
+     *
+     * @param object $entity
+     * @param ObjectManager $objectManager
+     * @param array $changeSet
+     */
+    public function __construct($entity, ObjectManager $objectManager, array &$changeSet)
+    {
+        parent::__construct($entity, $objectManager);
+
+        $this->entityChangeSet = &$changeSet;
+    }
+
+    /**
+     * Retrieve entity changeset.
+     *
+     * @return array
+     */
+    public function getEntityChangeSet()
+    {
+        return $this->entityChangeSet;
+    }
+
+    /**
+     * Check if field has a changeset.
+     *
+     * @return boolean
+     */
+    public function hasChangedField($field)
+    {
+        return isset($this->entityChangeSet[$field]);
+    }
+
+    /**
+     * Get the old value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getOldValue($field)
+    {
+        $this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][0];
+    }
+
+    /**
+     * Get the new value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getNewValue($field)
+    {
+        $this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][1];
+    }
+
+    /**
+     * Set the new value of this field.
+     *
+     * @param string $field
+     * @param mixed $value
+     */
+    public function setNewValue($field, $value)
+    {
+        $this->assertValidField($field);
+
+        $this->entityChangeSet[$field][1] = $value;
+    }
+
+    /**
+     * Assert the field exists in changeset.
+     *
+     * @param string $field
+     */
+    private function assertValidField($field)
+    {
+        if ( ! isset($this->entityChangeSet[$field])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
+                $field,
+                get_class($this->getEntity())
+            ));
+        }
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ManagerRegistry.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ManagerRegistry.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ManagerRegistry.php	(revision 345)
@@ -0,0 +1,112 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+interface ManagerRegistry extends ConnectionRegistry
+{
+    /**
+     * Gets the default object manager name.
+     *
+     * @return string The default object manager name
+     */
+    function getDefaultManagerName();
+
+    /**
+     * Gets a named object manager.
+     *
+     * @param string $name The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager
+     */
+    function getManager($name = null);
+
+    /**
+     * Gets an array of all registered object managers
+     *
+     * @return array An array of ObjectManager instances
+     */
+    function getManagers();
+
+    /**
+     * Resets a named object manager.
+     *
+     * This method is useful when an object manager has been closed
+     * because of a rollbacked transaction AND when you think that
+     * it makes sense to get a new one to replace the closed one.
+     *
+     * Be warned that you will get a brand new object manager as
+     * the existing one is not useable anymore. This means that any
+     * other object with a dependency on this object manager will
+     * hold an obsolete reference. You can inject the registry instead
+     * to avoid this problem.
+     *
+     * @param string $name The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager
+     */
+    function resetManager($name = null);
+
+    /**
+     * Resolves a registered namespace alias to the full namespace.
+     *
+     * This method looks for the alias in all registered object managers.
+     *
+     * @param string $alias The alias
+     *
+     * @return string The full namespace
+     */
+    function getAliasNamespace($alias);
+
+    /**
+     * Gets all connection names.
+     *
+     * @return array An array of connection names
+     */
+    function getManagerNames();
+
+    /**
+     * Gets the ObjectRepository for an persistent object.
+     *
+     * @param string $persistentObject        The name of the persistent object.
+     * @param string $persistentManagerName The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectRepository
+     */
+    function getRepository($persistentObject, $persistentManagerName = null);
+
+    /**
+     * Gets the object manager associated with a given class.
+     *
+     * @param string $class A persistent object class name
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager|null
+     */
+    function getManagerForClass($class);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php	(revision 345)
@@ -0,0 +1,359 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
+ * metadata mapping informations of a class which describes how a class should be mapped
+ * to a relational database.
+ *
+ * This class was abstracted from the ORM ClassMetadataFactory
+ *
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+abstract class AbstractClassMetadataFactory implements ClassMetadataFactory
+{
+    /**
+     * Salt used by specific Object Manager implementation.
+     *
+     * @var string
+     */
+    protected $cacheSalt = "\$CLASSMETADATA";
+
+    /**
+     * @var \Doctrine\Common\Cache\Cache
+     */
+    private $cacheDriver;
+
+    /**
+     * @var array
+     */
+    private $loadedMetadata = array();
+
+    /**
+     * @var bool
+     */
+    protected $initialized = false;
+
+    /**
+     * @var ReflectionService
+     */
+    private $reflectionService;
+
+    /**
+     * Sets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @param Doctrine\Common\Cache\Cache $cacheDriver
+     */
+    public function setCacheDriver(Cache $cacheDriver = null)
+    {
+        $this->cacheDriver = $cacheDriver;
+    }
+
+    /**
+     * Gets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @return Doctrine\Common\Cache\Cache
+     */
+    public function getCacheDriver()
+    {
+        return $this->cacheDriver;
+    }
+
+    /**
+     * Return an array of all the loaded metadata currently in memory.
+     *
+     * @return array
+     */
+    public function getLoadedMetadata()
+    {
+        return $this->loadedMetadata;
+    }
+
+    /**
+     * Forces the factory to load the metadata of all classes known to the underlying
+     * mapping driver.
+     *
+     * @return array The ClassMetadata instances of all mapped classes.
+     */
+    public function getAllMetadata()
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $driver = $this->getDriver();
+        $metadata = array();
+        foreach ($driver->getAllClassNames() as $className) {
+            $metadata[] = $this->getMetadataFor($className);
+        }
+
+        return $metadata;
+    }
+
+    /**
+     * Lazy initialization of this stuff, especially the metadata driver,
+     * since these are not needed at all when a metadata cache is active.
+     *
+     * @return void
+     */
+    abstract protected function initialize();
+
+    /**
+     * Get the fully qualified class-name from the namespace alias.
+     *
+     * @param string $namespaceAlias
+     * @param string $simpleClassName
+     * @return string
+     */
+    abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName);
+
+    /**
+     * Return the mapping driver implementation.
+     *
+     * @return MappingDriver
+     */
+    abstract protected function getDriver();
+
+    /**
+     * Wakeup reflection after ClassMetadata gets unserialized from cache.
+     *
+     * @param ClassMetadata $class
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService);
+
+    /**
+     * Initialize Reflection after ClassMetadata was constructed.
+     *
+     * @param ClassMetadata $class
+     * @param ReflectionSErvice $reflService
+     * @return void
+     */
+    abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService);
+
+    /**
+     * Gets the class metadata descriptor for a class.
+     *
+     * @param string $className The name of the class.
+     * @return Doctrine\Common\Persistence\Mapping\ClassMetadata
+     */
+    public function getMetadataFor($className)
+    {
+        if ( ! isset($this->loadedMetadata[$className])) {
+            $realClassName = $className;
+
+            // Check for namespace alias
+            if (strpos($className, ':') !== false) {
+                list($namespaceAlias, $simpleClassName) = explode(':', $className);
+                $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName);
+
+                if (isset($this->loadedMetadata[$realClassName])) {
+                    // We do not have the alias name in the map, include it
+                    $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+
+                    return $this->loadedMetadata[$realClassName];
+                }
+            }
+
+            if ($this->cacheDriver) {
+                if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) !== false) {
+                    $this->loadedMetadata[$realClassName] = $cached;
+                    $this->wakeupReflection($cached, $this->getReflectionService());
+                } else {
+                    foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
+                        $this->cacheDriver->save(
+                            $loadedClassName . $this->cacheSalt, $this->loadedMetadata[$loadedClassName], null
+                        );
+                    }
+                }
+            } else {
+                $this->loadMetadata($realClassName);
+            }
+
+            if ($className != $realClassName) {
+                // We do not have the alias name in the map, include it
+                $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+            }
+        }
+
+        return $this->loadedMetadata[$className];
+    }
+
+    /**
+     * Checks whether the factory has the metadata for a class loaded already.
+     *
+     * @param string $className
+     * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+     */
+    public function hasMetadataFor($className)
+    {
+        return isset($this->loadedMetadata[$className]);
+    }
+
+    /**
+     * Sets the metadata descriptor for a specific class.
+     *
+     * NOTE: This is only useful in very special cases, like when generating proxy classes.
+     *
+     * @param string $className
+     * @param ClassMetadata $class
+     */
+    public function setMetadataFor($className, $class)
+    {
+        $this->loadedMetadata[$className] = $class;
+    }
+
+    /**
+     * Get array of parent classes for the given entity class
+     *
+     * @param string $name
+     * @return array $parentClasses
+     */
+    protected function getParentClasses($name)
+    {
+        // Collect parent classes, ignoring transient (not-mapped) classes.
+        $parentClasses = array();
+        foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
+            if ( ! $this->getDriver()->isTransient($parentClass)) {
+                $parentClasses[] = $parentClass;
+            }
+        }
+        return $parentClasses;
+    }
+
+    /**
+     * Loads the metadata of the class in question and all it's ancestors whose metadata
+     * is still not loaded.
+     *
+     * @param string $name The name of the class for which the metadata should get loaded.
+     * @param array  $tables The metadata collection to which the loaded metadata is added.
+     */
+    protected function loadMetadata($name)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $loaded = array();
+
+        $parentClasses = $this->getParentClasses($name);
+        $parentClasses[] = $name;
+
+        // Move down the hierarchy of parent classes, starting from the topmost class
+        $parent = null;
+        $rootEntityFound = false;
+        $visited = array();
+        $reflService = $this->getReflectionService();
+        foreach ($parentClasses as $className) {
+            if (isset($this->loadedMetadata[$className])) {
+                $parent = $this->loadedMetadata[$className];
+                if (isset($parent->isMappedSuperclass) && $parent->isMappedSuperclass === false) {
+                    $rootEntityFound = true;
+                    array_unshift($visited, $className);
+                }
+                continue;
+            }
+
+            $class = $this->newClassMetadataInstance($className);
+            $this->initializeReflection($class, $reflService);
+
+            $this->doLoadMetadata($class, $parent, $rootEntityFound);
+
+            $this->loadedMetadata[$className] = $class;
+
+            $parent = $class;
+
+            if (isset($parent->isMappedSuperclass) && $class->isMappedSuperclass === false) {
+                $rootEntityFound = true;
+                array_unshift($visited, $className);
+            }
+
+            $this->wakeupReflection($class, $reflService);
+
+            $loaded[] = $className;
+        }
+
+        return $loaded;
+    }
+
+    /**
+     * Actually load the metadata from the underlying metadata
+     *
+     * @param ClassMetadata $class
+     * @param ClassMetadata $parent
+     * @param bool $rootEntityFound
+     * @return void
+     */
+    abstract protected function doLoadMetadata($class, $parent, $rootEntityFound);
+
+    /**
+     * Creates a new ClassMetadata instance for the given class name.
+     *
+     * @param string $className
+     * @return ClassMetadata
+     */
+    abstract protected function newClassMetadataInstance($className);
+
+    /**
+     * Check if this class is mapped by this Object Manager + ClassMetadata configuration
+     *
+     * @param $class
+     * @return bool
+     */
+    public function isTransient($class)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        return $this->getDriver()->isTransient($class);
+    }
+
+    /**
+     * Set reflectionService.
+     *
+     * @param ReflectionService $reflectionService
+     */
+    public function setReflectionService(ReflectionService $reflectionService)
+    {
+        $this->reflectionService = $reflectionService;
+    }
+
+    /**
+     * Get the reflection service associated with this metadata factory.
+     *
+     * @return ReflectionService
+     */
+    public function getReflectionService()
+    {
+        if ($this->reflectionService === null) {
+            $this->reflectionService = new RuntimeReflectionService();
+        }
+        return $this->reflectionService;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadata.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadata.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadata.php	(revision 345)
@@ -0,0 +1,165 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Contract for a Doctrine persistence layer ClassMetadata class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ClassMetadata
+{
+    /**
+     * Get fully-qualified class name of this persistent class.
+     *
+     * @return string
+     */
+    function getName();
+
+    /**
+     * Gets the mapped identifier field name.
+     *
+     * The returned structure is an array of the identifier field names.
+     *
+     * @return array
+     */
+    function getIdentifier();
+
+    /**
+     * Gets the ReflectionClass instance for this mapped class.
+     *
+     * @return ReflectionClass
+     */
+    function getReflectionClass();
+
+    /**
+     * Checks if the given field name is a mapped identifier for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isIdentifier($fieldName);
+
+    /**
+     * Checks if the given field is a mapped property for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function hasField($fieldName);
+
+    /**
+     * Checks if the given field is a mapped association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function hasAssociation($fieldName);
+
+    /**
+     * Checks if the given field is a mapped single valued association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isSingleValuedAssociation($fieldName);
+
+    /**
+     * Checks if the given field is a mapped collection valued association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isCollectionValuedAssociation($fieldName);
+
+    /**
+     * A numerically indexed list of field names of this persistent class.
+     *
+     * This array includes identifier fields if present on this class.
+     *
+     * @return array
+     */
+    function getFieldNames();
+
+    /**
+     * Returns an array of identifier field names numerically indexed.
+     *
+     * @return array
+     */
+    function getIdentifierFieldNames();
+
+    /**
+     * A numerically indexed list of association names of this persistent class.
+     *
+     * This array includes identifier associations if present on this class.
+     *
+     * @return array
+     */
+    function getAssociationNames();
+
+    /**
+     * Returns a type name of this field.
+     *
+     * This type names can be implementation specific but should at least include the php types:
+     * integer, string, boolean, float/double, datetime.
+     *
+     * @param string $fieldName
+     * @return string
+     */
+    function getTypeOfField($fieldName);
+
+    /**
+     * Returns the target class name of the given association.
+     *
+     * @param string $assocName
+     * @return string
+     */
+    function getAssociationTargetClass($assocName);
+
+    /**
+     * Checks if the association is the inverse side of a bidirectional association
+     *
+     * @param string $assocName
+     * @return boolean
+     */
+    function isAssociationInverseSide($assocName);
+
+    /**
+     * Returns the target field of the owning side of the association
+     *
+     * @param string $assocName
+     * @return string
+     */
+    function getAssociationMappedByTargetField($assocName);
+
+    /**
+     * Return the identifier of this object as an array with field name as key.
+     *
+     * Has to return an empty array if no identifier isset.
+     *
+     * @param object $object
+     * @return array
+     */
+    function getIdentifierValues($object);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php	(revision 345)
@@ -0,0 +1,74 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Contract for a Doctrine persistence layer ClassMetadata class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ClassMetadataFactory
+{
+    /**
+     * Forces the factory to load the metadata of all classes known to the underlying
+     * mapping driver.
+     *
+     * @return array The ClassMetadata instances of all mapped classes.
+     */
+    function getAllMetadata();
+
+    /**
+     * Gets the class metadata descriptor for a class.
+     *
+     * @param string $className The name of the class.
+     * @return ClassMetadata
+     */
+    function getMetadataFor($className);
+
+    /**
+     * Checks whether the factory has the metadata for a class loaded already.
+     *
+     * @param string $className
+     * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+     */
+    function hasMetadataFor($className);
+
+    /**
+     * Sets the metadata descriptor for a specific class.
+     *
+     * @param string $className
+     * @param ClassMetadata $class
+     */
+    function setMetadataFor($className, $class);
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped directly or as a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    function isTransient($className);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php	(revision 345)
@@ -0,0 +1,214 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\Common\Annotations\AnnotationRegistry,
+    Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The AnnotationDriver reads the mapping metadata from docblock annotations.
+ *
+ * @since 2.2
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+abstract class AnnotationDriver implements MappingDriver
+{
+    /**
+     * The AnnotationReader.
+     *
+     * @var AnnotationReader
+     */
+    protected $reader;
+
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $fileExtension = '.php';
+
+    /**
+     * Cache for AnnotationDriver#getAllClassNames()
+     *
+     * @var array
+     */
+    protected $classNames;
+
+    /**
+     * Name of the entity annotations as keys
+     *
+     * @var array
+     */
+    protected $entityAnnotationClasses = array();
+
+    /**
+     * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
+     * docblock annotations.
+     *
+     * @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
+     * @param string|array $paths One or multiple paths where mapping classes can be found.
+     */
+    public function __construct($reader, $paths = null)
+    {
+        $this->reader = $reader;
+        if ($paths) {
+            $this->addPaths((array) $paths);
+        }
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Retrieve the current annotation reader
+     *
+     * @return AnnotationReader
+     */
+    public function getReader()
+    {
+        return $this->reader;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Whether the class with the specified name is transient. Only non-transient
+     * classes, that is entities and mapped superclasses, should have their metadata loaded.
+     *
+     * A class is non-transient if it is annotated with an annotation
+     * from the {@see AnnotationDriver::entityAnnotationClasses}.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
+
+        foreach ($classAnnotations as $annot) {
+            if (isset($this->entityAnnotationClasses[get_class($annot)])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classNames !== null) {
+            return $this->classNames;
+        }
+
+        if (!$this->paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->paths as $path) {
+            if ( ! is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RegexIterator(
+                new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                ),
+                '/^.+' . str_replace('.', '\.', $this->fileExtension) . '$/i',
+                \RecursiveRegexIterator::GET_MATCH
+            );
+
+            foreach ($iterator as $file) {
+                $sourceFile = realpath($file[0]);
+
+                require_once $sourceFile;
+
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->classNames = $classes;
+
+        return $classes;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php	(revision 345)
@@ -0,0 +1,169 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * Locate the file that contains the metadata information for a given class name.
+ *
+ * This behavior is inpependent of the actual content of the file. It just detects
+ * the file which is responsible for the given class name.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class DefaultFileLocator implements FileLocator
+{
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $fileExtension;
+
+    /**
+     * Initializes a new FileDriver that looks in the given path(s) for mapping
+     * documents and operates in the specified operating mode.
+     *
+     * @param string|array $paths One or multiple paths where mapping documents can be found.
+     */
+    public function __construct($paths, $fileExtension = null)
+    {
+        $this->addPaths((array) $paths);
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function findMappingFile($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+        // Check whether file exists
+        foreach ($this->paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return $path . DIRECTORY_SEPARATOR . $fileName;
+            }
+        }
+
+        throw MappingException::mappingFileNotFound($className, $fileName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames($globalBasename)
+    {
+        $classes = array();
+
+        if ($this->paths) {
+            foreach ($this->paths as $path) {
+                if ( ! is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    $classes[] = str_replace('.', '\\', $fileName);
+                }
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function fileExists($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+        // Check whether file exists
+        foreach ((array) $this->paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php	(revision 345)
@@ -0,0 +1,178 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * Base driver for file-based metadata drivers.
+ *
+ * A file driver operates in a mode where it loads the mapping files of individual
+ * classes on demand. This requires the user to adhere to the convention of 1 mapping
+ * file per class and the file names of the mapping files must correspond to the full
+ * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+abstract class FileDriver implements MappingDriver
+{
+    /**
+     * @var FileLocator
+     */
+    protected $locator;
+
+    /**
+     * @var array
+     */
+    protected $classCache;
+
+    /**
+     * @var string
+     */
+    protected $globalBasename;
+
+    /**
+     * Initializes a new FileDriver that looks in the given path(s) for mapping
+     * documents and operates in the specified operating mode.
+     *
+     * @param string|array|FileLocator $paths A FileLocator or one/multiple paths where mapping documents can be found.
+     * @param string $fileExtension
+     */
+    public function __construct($locator, $fileExtension = null)
+    {
+        if ($locator instanceof FileLocator) {
+            $this->locator = $locator;
+        } else {
+            $this->locator = new DefaultFileLocator((array)$locator, $fileExtension);
+        }
+    }
+
+    public function setGlobalBasename($file)
+    {
+        $this->globalBasename = $file;
+    }
+
+    public function getGlobalBasename()
+    {
+        return $this->globalBasename;
+    }
+
+    /**
+     * Get the element of schema meta data for the class from the mapping file.
+     * This will lazily load the mapping file if it is not loaded yet
+     *
+     * @return array $element  The element of schema meta data
+     */
+    public function getElement($className)
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        if (isset($this->classCache[$className])) {
+            return $this->classCache[$className];
+        }
+
+        $result = $this->loadMappingFile($this->locator->findMappingFile($className));
+
+        return $result[$className];
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        if (isset($this->classCache[$className])) {
+            return false;
+        }
+
+        return !$this->locator->fileExists($className);
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        $classNames = (array)$this->locator->getAllClassNames($this->globalBasename);
+        if ($this->classCache) {
+            $classNames = array_merge(array_keys($this->classCache), $classNames);
+        }
+        return $classNames;
+    }
+
+    /**
+     * Loads a mapping file with the given name and returns a map
+     * from class/entity names to their corresponding file driver elements.
+     *
+     * @param string $file The mapping file to load.
+     * @return array
+     */
+    abstract protected function loadMappingFile($file);
+
+    /**
+     * Initialize the class cache from all the global files.
+     *
+     * Using this feature adds a substantial performance hit to file drivers as
+     * more metadata has to be loaded into memory than might actually be
+     * necessary. This may not be relevant to scenarios where caching of
+     * metadata is in place, however hits very hard in scenarios where no
+     * caching is used.
+     *
+     * @return void
+     */
+    protected function initialize()
+    {
+        $this->classCache = array();
+        if (null !== $this->globalBasename) {
+            foreach ($this->locator->getPaths() as $path) {
+                $file = $path.'/'.$this->globalBasename.$this->locator->getFileExtension();
+                if (is_file($file)) {
+                    $this->classCache = array_merge(
+                        $this->classCache,
+                        $this->loadMappingFile($file)
+                    );
+                }
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php	(revision 345)
@@ -0,0 +1,69 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+/**
+ * Locate the file that contains the metadata information for a given class name.
+ *
+ * This behavior is inpependent of the actual content of the file. It just detects
+ * the file which is responsible for the given class name.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface FileLocator
+{
+    /**
+     * Locate mapping file for the given class name.
+     *
+     * @param string $className
+     * @return string
+     */
+    function findMappingFile($className);
+
+    /**
+     * Get all class names that are found with this file locator.
+     *
+     * @param string $globalBasename Passed to allow excluding the basename
+     * @return array
+     */
+    function getAllClassNames($globalBasename);
+
+    /**
+     * Check if a file can be found for this class name.
+     *
+     * @return bool
+     */
+    function fileExists($className);
+
+    /**
+     * Get all the paths that this file locator looks for mapping files.
+     *
+     * @return array
+     */
+    function getPaths();
+
+    /**
+     * Get the file extension that mapping files are suffixed with.
+     *
+     * @return string
+     */
+    function getFileExtension();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php	(revision 345)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Contract for metadata drivers.
+ *
+ * @since 2.2
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ */
+interface MappingDriver
+{
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadata $metadata
+     */
+    function loadMetadataForClass($className, ClassMetadata $metadata);
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    function getAllClassNames();
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    function isTransient($className);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php	(revision 345)
@@ -0,0 +1,125 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
+    Doctrine\Common\Persistence\Mapping\ClassMetadata,
+    Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The DriverChain allows you to add multiple other mapping drivers for
+ * certain namespaces
+ *
+ * @since  2.2
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class MappingDriverChain implements MappingDriver
+{
+    /**
+     * @var array
+     */
+    private $drivers = array();
+
+    /**
+     * Add a nested driver.
+     *
+     * @param Driver $nestedDriver
+     * @param string $namespace
+     */
+    public function addDriver(MappingDriver $nestedDriver, $namespace)
+    {
+        $this->drivers[$namespace] = $nestedDriver;
+    }
+
+    /**
+     * Get the array of nested drivers.
+     *
+     * @return array $drivers
+     */
+    public function getDrivers()
+    {
+        return $this->drivers;
+    }
+
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadataInfo $metadata
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        foreach ($this->drivers as $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                $driver->loadMetadataForClass($className, $metadata);
+                return;
+            }
+        }
+
+        throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers));
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        $classNames = array();
+        $driverClasses = array();
+        foreach ($this->drivers AS $namespace => $driver) {
+            $oid = spl_object_hash($driver);
+            if (!isset($driverClasses[$oid])) {
+                $driverClasses[$oid] = $driver->getAllClassNames();
+            }
+
+            foreach ($driverClasses[$oid] AS $className) {
+                if (strpos($className, $namespace) === 0) {
+                    $classNames[$className] = true;
+                }
+            }
+        }
+        return array_keys($classNames);
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     *
+     * This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        foreach ($this->drivers AS $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                return $driver->isTransient($className);
+            }
+        }
+
+        // class isTransient, i.e. not an entity or mapped superclass
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * The PHPDriver includes php files which just populate ClassMetadataInfo
+ * instances with plain php code
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class PHPDriver extends FileDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $metadata;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($locator, $fileExtension = null)
+    {
+        $fileExtension = ".php";
+        parent::__construct($locator, $fileExtension);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        $this->metadata = $metadata;
+        $this->loadMappingFile($this->locator->findMappingFile($className));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadMappingFile($file)
+    {
+        $metadata = $this->metadata;
+        include $file;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php	(revision 345)
@@ -0,0 +1,131 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The StaticPHPDriver calls a static loadMetadata() method on your entity
+ * classes where you can manually populate the ClassMetadata instance.
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class StaticPHPDriver implements MappingDriver
+{
+    /**
+     * Paths of entity directories.
+     *
+     * @var array
+     */
+    private $paths = array();
+
+    /**
+     * Map of all class names.
+     *
+     * @var array
+     */
+    private $classNames;
+
+    public function __construct($paths)
+    {
+        $this->addPaths((array) $paths);
+    }
+
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        $className::loadMetadata($metadata);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classNames !== null) {
+            return $this->classNames;
+        }
+
+        if (!$this->paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->paths as $path) {
+            if (!is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RecursiveIteratorIterator(
+                new \RecursiveDirectoryIterator($path),
+                \RecursiveIteratorIterator::LEAVES_ONLY
+            );
+
+            foreach ($iterator as $file) {
+                if ($file->getBasename('.php') == $file->getBasename()) {
+                    continue;
+                }
+
+                $sourceFile = realpath($file->getPathName());
+                require_once $sourceFile;
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->classNames = $classes;
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isTransient($className)
+    {
+        return ! method_exists($className, 'loadMetadata');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php	(revision 345)
@@ -0,0 +1,198 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The Symfony File Locator makes a simplifying assumptions compared
+ * to the DefaultFileLocator. By assuming paths only contain entities of a certain
+ * namespace the mapping files consists of the short classname only.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @license MIT
+ */
+class SymfonyFileLocator implements FileLocator
+{
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * A map of mapping directory path to namespace prefix used to expand class shortnames.
+     *
+     * @var array
+     */
+    protected $prefixes = array();
+
+    /**
+     * File extension that is searched for.
+     *
+     * @var string
+     */
+    protected $fileExtension;
+
+    public function __construct(array $prefixes, $fileExtension = null)
+    {
+        $this->addNamespacePrefixes($prefixes);
+        $this->fileExtension = $fileExtension;
+    }
+
+    public function addNamespacePrefixes(array $prefixes)
+    {
+        $this->prefixes = array_merge($this->prefixes, $prefixes);
+        $this->paths = array_merge($this->paths, array_keys($prefixes));
+    }
+
+    public function getNamespacePrefixes()
+    {
+        return $this->prefixes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function fileExists($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension;
+        foreach ($this->paths as $path) {
+            if (!isset($this->prefixes[$path])) {
+                // global namespace class
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return true;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension;
+            return is_file($filename);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames($globalBasename = null)
+    {
+        $classes = array();
+
+        if ($this->paths) {
+            foreach ((array) $this->paths as $path) {
+                if (!is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    if (isset($this->prefixes[$path])) {
+                        $classes[] = $this->prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
+                    } else {
+                        $classes[] = str_replace('.', '\\', $fileName);
+                    }
+                }
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function findMappingFile($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension;
+        foreach ($this->paths as $path) {
+            if (!isset($this->prefixes[$path])) {
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return $path.DIRECTORY_SEPARATOR.$defaultFileName;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension;
+            if (is_file($filename)) {
+                return $filename;
+            }
+
+            throw MappingException::mappingFileNotFound($className, $filename);
+        }
+
+        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->fileExtension);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/MappingException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/MappingException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/MappingException.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * A MappingException indicates that something is wrong with the mapping setup.
+ *
+ * @since 2.2
+ */
+class MappingException extends \Exception
+{
+    public static function classNotFoundInNamespaces($className, $namespaces)
+    {
+        return new self("The class '" . $className . "' was not found in the ".
+            "chain configured namespaces " . implode(", ", $namespaces));
+    }
+
+    public static function pathRequired()
+    {
+        return new self("Specifying the paths to your entities is required ".
+            "in the AnnotationDriver to retrieve all class names.");
+    }
+
+    public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null)
+    {
+        if ( ! empty($path)) {
+            $path = '[' . $path . ']';
+        }
+
+        return new self(
+            'File mapping drivers must have a valid directory path, ' .
+            'however the given path ' . $path . ' seems to be incorrect!'
+        );
+    }
+
+    public static function mappingFileNotFound($entityName, $fileName)
+    {
+        return new self("No mapping file found named '$fileName' for class '$entityName'.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ReflectionService.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ReflectionService.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/ReflectionService.php	(revision 345)
@@ -0,0 +1,80 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Very simple reflection service abstraction.
+ *
+ * This is required inside metadata layers that may require either
+ * static or runtime reflection.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    function getParentClasses($class);
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $class
+     * @return string
+     */
+    function getClassShortName($class);
+
+    /**
+     * @param string $class
+     * @return string
+     */
+    function getClassNamespace($class);
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    function getClass($class);
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    function getAccessibleProperty($class, $property);
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    function hasPublicMethod($class, $method);
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php	(revision 345)
@@ -0,0 +1,103 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use ReflectionClass;
+use ReflectionProperty;
+
+/**
+ * PHP Runtime Reflection Service
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class RuntimeReflectionService implements ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    public function getParentClasses($class)
+    {
+        return class_parents($class);
+    }
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $class
+     * @return string
+     */
+    public function getClassShortName($class)
+    {
+        $r = new ReflectionClass($class);
+        return $r->getShortName();
+    }
+
+    /**
+     * @param string $class
+     * @return string
+     */
+    public function getClassNamespace($class)
+    {
+        $r = new ReflectionClass($class);
+        return $r->getNamespaceName();
+    }
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    public function getClass($class)
+    {
+        return new ReflectionClass($class);
+    }
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    public function getAccessibleProperty($class, $property)
+    {
+        $property = new ReflectionProperty($class, $property);
+        $property->setAccessible(true);
+
+		return $property;
+    }
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    public function hasPublicMethod($class, $method)
+    {
+        return method_exists($class, $method) && is_callable(array($class, $method));
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php	(revision 345)
@@ -0,0 +1,107 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use ReflectionClass;
+use ReflectionProperty;
+
+/**
+ * PHP Runtime Reflection Service
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class StaticReflectionService implements ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    public function getParentClasses($class)
+    {
+        return array();
+    }
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $className
+     * @return string
+     */
+    public function getClassShortName($className)
+    {
+        if (strpos($className, '\\') !== false) {
+            $className = substr($className, strrpos($className, "\\")+1);
+        }
+        return $className;
+    }
+
+    /**
+     * Return the namespace of a class.
+     *
+     * @param string $className
+     * @return string
+     */
+    public function getClassNamespace($className)
+    {
+        $namespace = '';
+        if (strpos($className, '\\') !== false) {
+            $namespace = strrev(substr( strrev($className), strpos(strrev($className), '\\')+1 ));
+        }
+        return $namespace;
+    }
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    public function getClass($class)
+    {
+        return null;
+    }
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    public function getAccessibleProperty($class, $property)
+    {
+        return null;
+    }
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    public function hasPublicMethod($class, $method)
+    {
+        return method_exists($class, $method) && is_callable(array($class, $method));
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManager.php	(revision 345)
@@ -0,0 +1,143 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract for a Doctrine persistence layer ObjectManager class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ObjectManager
+{
+    /**
+     * Finds a object by its identifier.
+     *
+     * This is just a convenient shortcut for getRepository($className)->find($id).
+     *
+     * @param string
+     * @param mixed
+     * @return object
+     */
+    function find($className, $id);
+
+    /**
+     * Tells the ObjectManager to make an instance managed and persistent.
+     *
+     * The object will be entered into the database as a result of the flush operation.
+     *
+     * NOTE: The persist operation always considers objects that are not yet known to
+     * this ObjectManager as NEW. Do not pass detached objects to the persist operation.
+     *
+     * @param object $object The instance to make managed and persistent.
+     */
+    function persist($object);
+
+    /**
+     * Removes an object instance.
+     *
+     * A removed object will be removed from the database as a result of the flush operation.
+     *
+     * @param object $object The object instance to remove.
+     */
+    function remove($object);
+
+    /**
+     * Merges the state of a detached object into the persistence context
+     * of this ObjectManager and returns the managed copy of the object.
+     * The object passed to merge will not become associated/managed with this ObjectManager.
+     *
+     * @param object $object
+     */
+    function merge($object);
+
+    /**
+     * Detaches an object from the ObjectManager, causing a managed object to
+     * become detached. Unflushed changes made to the object if any
+     * (including removal of the object), will not be synchronized to the database.
+     * Objects which previously referenced the detached object will continue to
+     * reference it.
+     *
+     * @param object $object The object to detach.
+     */
+    function detach($object);
+
+    /**
+     * Refreshes the persistent state of an object from the database,
+     * overriding any local changes that have not yet been persisted.
+     *
+     * @param object $object The object to refresh.
+     */
+    function refresh($object);
+
+    /**
+     * Flushes all changes to objects that have been queued up to now to the database.
+     * This effectively synchronizes the in-memory state of managed objects with the
+     * database.
+     */
+    function flush();
+
+    /**
+     * Gets the repository for a class.
+     *
+     * @param string $className
+     * @return \Doctrine\Common\Persistence\ObjectRepository
+     */
+    function getRepository($className);
+
+    /**
+     * Returns the ClassMetadata descriptor for a class.
+     *
+     * The class name must be the fully-qualified class name without a leading backslash
+     * (as it is returned by get_class($obj)).
+     *
+     * @param string $className
+     * @return \Doctrine\Common\Persistence\Mapping\ClassMetadata
+     */
+    function getClassMetadata($className);
+
+    /**
+     * Gets the metadata factory used to gather the metadata of classes.
+     *
+     * @return Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
+     */
+    function getMetadataFactory();
+
+    /**
+     * Helper method to initialize a lazy loading proxy or persistent collection.
+     *
+     * This method is a no-op for other objects.
+     *
+     * @param object $obj
+     */
+    function initializeObject($obj);
+
+    /**
+     * Check if the object is part of the current UnitOfWork and therefore
+     * managed.
+     *
+     * @param object $object
+     * @return bool
+     */
+    function contains($object);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManagerAware.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManagerAware.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectManagerAware.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Makes a Persistent Objects aware of its own object-manager.
+ *
+ * Using this interface the managing object manager and class metadata instances
+ * are injected into the persistent object after construction. This allows
+ * you to implement ActiveRecord functionality on top of the persistance-ignorance
+ * that Doctrine propagates.
+ *
+ * Word of Warning: This is a very powerful hook to change how you can work with your domain models.
+ * Using this hook will break the Single Responsibility Principle inside your Domain Objects
+ * and increase the coupling of database and objects.
+ *
+ * Every ObjectManager has to implement this functionality itself.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface ObjectManagerAware
+{
+    /**
+     * Injects responsible ObjectManager and the ClassMetadata into this persistent object.
+     *
+     * @param ObjectManager $objectManager
+     * @param ClassMetadata $classMetadata
+     */
+    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectRepository.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectRepository.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/ObjectRepository.php	(revision 345)
@@ -0,0 +1,78 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract for a Doctrine persistence layer ObjectRepository class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ObjectRepository
+{
+    /**
+     * Finds an object by its primary key / identifier.
+     *
+     * @param $id The identifier.
+     * @return object The object.
+     */
+    function find($id);
+
+    /**
+     * Finds all objects in the repository.
+     *
+     * @return mixed The objects.
+     */
+    function findAll();
+
+    /**
+     * Finds objects by a set of criteria.
+     *
+     * Optionally sorting and limiting details can be passed. An implementation may throw
+     * an UnexpectedValueException if certain values of the sorting or limiting details are
+     * not supported.
+     *
+     * @throws UnexpectedValueException
+     * @param array $criteria
+     * @param array|null $orderBy
+     * @param int|null $limit
+     * @param int|null $offset
+     * @return mixed The objects.
+     */
+    function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null);
+
+    /**
+     * Finds a single object by a set of criteria.
+     *
+     * @param array $criteria
+     * @return object The object.
+     */
+    function findOneBy(array $criteria);
+
+    /**
+     * Returns the class name of the object managed by the repository
+     *
+     * @return string
+     */
+    function getClassName();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/PersistentObject.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/PersistentObject.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/PersistentObject.php	(revision 345)
@@ -0,0 +1,233 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+
+/**
+ * PersistentObject base class that implements getter/setter methods for all mapped fields and associations
+ * by overriding __call.
+ *
+ * This class is a forward compatible implementation of the PersistentObject trait.
+ *
+ *
+ * Limitations:
+ *
+ * 1. All persistent objects have to be associated with a single ObjectManager, multiple
+ *    ObjectManagers are not supported. You can set the ObjectManager with `PersistentObject#setObjectManager()`.
+ * 2. Setters and getters only work if a ClassMetadata instance was injected into the PersistentObject.
+ *    This is either done on `postLoad` of an object or by accessing the global object manager.
+ * 3. There are no hooks for setters/getters. Just implement the method yourself instead of relying on __call().
+ * 4. Slower than handcoded implementations: An average of 7 method calls per access to a field and 11 for an association.
+ * 5. Only the inverse side associations get autoset on the owning side aswell. Setting objects on the owning side
+ *    will not set the inverse side associations.
+ *
+ * @example
+ *
+ *  PersistentObject::setObjectManager($em);
+ *
+ *  class Foo extends PersistentObject
+ *  {
+ *      private $id;
+ *  }
+ *
+ *  $foo = new Foo();
+ *  $foo->getId(); // method exists through __call
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class PersistentObject implements ObjectManagerAware
+{
+    /**
+     * @var ObjectManager
+     */
+    private static $objectManager;
+
+    /**
+     * @var ClassMetadata
+     */
+    private $cm;
+
+    /**
+     * Set the object manager responsible for all persistent object base classes.
+     *
+     * @param ObjectManager $objectManager
+     */
+    static public function setObjectManager(ObjectManager $objectManager = null)
+    {
+        self::$objectManager = $objectManager;
+    }
+
+    /**
+     * @return ObjectManager
+     */
+    static public function getObjectManager()
+    {
+        return self::$objectManager;
+    }
+
+    /**
+     * Inject Doctrine Object Manager
+     *
+     * @param ObjectManager $objectManager
+     * @param ClassMetadata $classMetadata
+     */
+    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
+    {
+        if ($objectManager !== self::$objectManager) {
+            throw new \RuntimeException("Trying to use PersistentObject with different ObjectManager instances. " .
+                "Was PersistentObject::setObjectManager() called?");
+        }
+
+        $this->cm = $classMetadata;
+    }
+
+    /**
+     * Sets a persistent fields value.
+     *
+     * @throws InvalidArgumentException - When the wrong target object type is passed to an association
+     * @throws BadMethodCallException - When no persistent field exists by that name.
+     * @param string $field
+     * @param array $args
+     * @return void
+     */
+    private function set($field, $args)
+    {
+        $this->initializeDoctrine();
+
+        if ($this->cm->hasField($field) && !$this->cm->isIdentifier($field)) {
+            $this->$field = $args[0];
+        } else if ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) {
+            $targetClass = $this->cm->getAssociationTargetClass($field);
+            if (!($args[0] instanceof $targetClass) && $args[0] !== null) {
+                throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'");
+            }
+            $this->$field = $args[0];
+            $this->completeOwningSide($field, $targetClass, $args[0]);
+        } else {
+            throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'");
+        }
+    }
+
+    /**
+     * Get persistent field value.
+     *
+     * @throws BadMethodCallException - When no persistent field exists by that name.
+     * @param string $field
+     * @return mixed
+     */
+    private function get($field)
+    {
+        $this->initializeDoctrine();
+
+        if ( $this->cm->hasField($field) || $this->cm->hasAssociation($field) ) {
+            return $this->$field;
+        } else {
+            throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'");
+        }
+    }
+
+    /**
+     * If this is an inverse side association complete the owning side.
+     *
+     * @param string $field
+     * @param ClassMetadata $targetClass
+     * @param object $targetObject
+     */
+    private function completeOwningSide($field, $targetClass, $targetObject)
+    {
+        // add this object on the owning side aswell, for obvious infinite recursion
+        // reasons this is only done when called on the inverse side.
+        if ($this->cm->isAssociationInverseSide($field)) {
+            $mappedByField = $this->cm->getAssociationMappedByTargetField($field);
+            $targetMetadata = self::$objectManager->getClassMetadata($targetClass);
+
+            $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? "add" : "set").$mappedByField;
+            $targetObject->$setter($this);
+        }
+    }
+
+    /**
+     * Add an object to a collection
+     *
+     * @param type $field
+     * @param assoc $args
+     */
+    private function add($field, $args)
+    {
+        $this->initializeDoctrine();
+
+        if ($this->cm->hasAssociation($field) && $this->cm->isCollectionValuedAssociation($field)) {
+            $targetClass = $this->cm->getAssociationTargetClass($field);
+            if (!($args[0] instanceof $targetClass)) {
+                throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'");
+            }
+            if (!($this->$field instanceof Collection)) {
+                $this->$field = new ArrayCollection($this->$field ?: array());
+            }
+            $this->$field->add($args[0]);
+            $this->completeOwningSide($field, $targetClass, $args[0]);
+        } else {
+            throw new \BadMethodCallException("There is no method add".$field."() on ".$this->cm->getName());
+        }
+    }
+
+    /**
+     * Initialize Doctrine Metadata for this class.
+     *
+     * @return void
+     */
+    private function initializeDoctrine()
+    {
+        if ($this->cm !== null) {
+            return;
+        }
+
+        if (!self::$objectManager) {
+            throw new \RuntimeException("No runtime object manager set. Call PersistentObject#setObjectManager().");
+        }
+
+        $this->cm = self::$objectManager->getClassMetadata(get_class($this));
+    }
+
+    /**
+     * Magic method that implements
+     *
+     * @param string $method
+     * @param array $args
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        $command = substr($method, 0, 3);
+        $field = lcfirst(substr($method, 3));
+        if ($command == "set") {
+            $this->set($field, $args);
+        } else if ($command == "get") {
+            return $this->get($field);
+        } else if ($command == "add") {
+            $this->add($field, $args);
+        } else {
+            throw new \BadMethodCallException("There is no method ".$method." on ".$this->cm->getName());
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Proxy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Proxy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Persistence/Proxy.php	(revision 345)
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Interface for proxy classes.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.2
+ */
+interface Proxy
+{
+    /**
+     * Marker for Proxy class names.
+     *
+     * @var string
+     */
+    const MARKER = '__CG__';
+
+    /**
+     * Length of the proxy marker
+     *
+     * @var int
+     */
+    const MARKER_LENGTH = 6;
+
+    /**
+     * Initialize this proxy if its not yet initialized.
+     *
+     * Acts as a no-op if already initialized.
+     *
+     * @return void
+     */
+    public function __load();
+
+    /**
+     * Is this proxy initialized or not.
+     *
+     * @return bool
+     */
+    public function __isInitialized();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/PropertyChangedListener.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/PropertyChangedListener.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/PropertyChangedListener.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Contract for classes that are potential listeners of a <tt>NotifyPropertyChanged</tt>
+ * implementor.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface PropertyChangedListener
+{
+    /**
+     * Notifies the listener of a property change.
+     *
+     * @param object $sender The object on which the property changed.
+     * @param string $propertyName The name of the property that changed.
+     * @param mixed $oldValue The old value of the property that changed.
+     * @param mixed $newValue The new value of the property that changed.
+     */
+    function propertyChanged($sender, $propertyName, $oldValue, $newValue);
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/ClassUtils.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/ClassUtils.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/ClassUtils.php	(revision 345)
@@ -0,0 +1,103 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+use Doctrine\Common\Persistence\Proxy;
+
+/**
+ * Class and reflection related functionality for objects that
+ * might or not be proxy objects at the moment.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes Schmitt <schmittjoh@gmail.com>
+ */
+class ClassUtils
+{
+    /**
+     * Get the real class name of a class name that could be a proxy.
+     *
+     * @param string
+     * @return string
+     */
+    public static function getRealClass($class)
+    {
+        if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
+            return $class;
+        }
+
+        return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
+    }
+
+    /**
+     * Get the real class name of an object (even if its a proxy)
+     *
+     * @param object
+     * @return string
+     */
+    public static function getClass($object)
+    {
+        return self::getRealClass(get_class($object));
+    }
+
+    /**
+     * Get the real parent class name of a class or object
+     *
+     * @param string
+     * @return string
+     */
+    public static function getParentClass($className)
+    {
+        return get_parent_class( self::getRealClass( $className ) );
+    }
+
+    /**
+     * Create a new reflection class
+     *
+     * @param string
+     * @return ReflectionClass
+     */
+    public static function newReflectionClass($class)
+    {
+        return new \ReflectionClass( self::getRealClass( $class ) );
+    }
+
+    /**
+     * Create a new reflection object
+     *
+     * @param object
+     * @return ReflectionObject
+     */
+    public static function newReflectionObject($object)
+    {
+        return self::newReflectionClass( self::getClass( $object ) );
+    }
+
+    /**
+     * Given a class name and a proxy namespace return the proxy name.
+     *
+     * @param string $className
+     * @param string $proxyNamespace
+     * @return string
+     */
+    public static function generateProxyClassName($className, $proxyNamespace)
+    {
+        return rtrim($proxyNamespace, '\\') . '\\'.Proxy::MARKER.'\\' . ltrim($className, '\\');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Debug.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Debug.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Debug.php	(revision 345)
@@ -0,0 +1,123 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+/**
+ * Static class containing most used debug methods.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ */
+final class Debug
+{
+    /**
+     * Private constructor (prevents from instantiation)
+     *
+     */
+    private function __construct() {}
+
+    /**
+     * Prints a dump of the public, protected and private properties of $var.
+     *
+     * @static
+     * @link http://xdebug.org/
+     * @param mixed $var
+     * @param integer $maxDepth Maximum nesting level for object properties
+     * @param boolean $stripTags Flag that indicate if output should strip HTML tags
+     */
+    public static function dump($var, $maxDepth = 2, $stripTags = true)
+    {
+        ini_set('html_errors', 'On');
+
+        if (extension_loaded('xdebug')) {
+            ini_set('xdebug.var_display_max_depth', $maxDepth);
+        }
+
+        $var = self::export($var, $maxDepth++);
+
+        ob_start();
+        var_dump($var);
+        $dump = ob_get_contents();
+        ob_end_clean();
+
+        echo ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump);
+
+        ini_set('html_errors', 'Off');
+    }
+
+    public static function export($var, $maxDepth)
+    {
+        $return = null;
+        $isObj = is_object($var);
+
+        if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) {
+            $var = $var->toArray();
+        }
+
+        if ($maxDepth) {
+            if (is_array($var)) {
+                $return = array();
+
+                foreach ($var as $k => $v) {
+                    $return[$k] = self::export($v, $maxDepth - 1);
+                }
+            } else if ($isObj) {
+                $return = new \stdclass();
+                if ($var instanceof \DateTime) {
+                    $return->__CLASS__ = "DateTime";
+                    $return->date = $var->format('c');
+                    $return->timezone = $var->getTimeZone()->getName();
+                } else {
+                    $reflClass = ClassUtils::newReflectionObject($var);
+                    $return->__CLASS__ = ClassUtils::getClass($var);
+
+                    if ($var instanceof \Doctrine\Common\Persistence\Proxy) {
+                        $return->__IS_PROXY__ = true;
+                        $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
+                    }
+
+                    foreach ($reflClass->getProperties() as $reflProperty) {
+                        $name  = $reflProperty->getName();
+
+                        $reflProperty->setAccessible(true);
+                        $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
+                    }
+                }
+            } else {
+                $return = $var;
+            }
+        } else {
+            $return = is_object($var) ? get_class($var)
+                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
+        }
+
+        return $return;
+    }
+
+    public static function toString($obj)
+    {
+        return method_exists('__toString', $obj) ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Inflector.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Inflector.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Util/Inflector.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+/*
+ *  $Id: Inflector.php 3189 2007-11-18 20:37:44Z meus $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+/**
+ * Doctrine inflector has static methods for inflecting text
+ *
+ * The methods in these classes are from several different sources collected
+ * across several different php projects and several different authors. The
+ * original author names and emails are not known
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 3189 $
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ */
+class Inflector
+{
+    /**
+     * Convert word in to the format for a Doctrine table name. Converts 'ModelName' to 'model_name'
+     *
+     * @param  string $word  Word to tableize
+     * @return string $word  Tableized word
+     */
+    public static function tableize($word)
+    {
+        return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
+    }
+
+    /**
+     * Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName'
+     *
+     * @param string  $word  Word to classify
+     * @return string $word  Classified word
+     */
+    public static function classify($word)
+    {
+        return str_replace(" ", "", ucwords(strtr($word, "_-", "  ")));
+    }
+
+    /**
+     * Camelize a word. This uses the classify() method and turns the first character to lowercase
+     *
+     * @param string $word
+     * @return string $word
+     */
+    public static function camelize($word)
+    {
+        return lcfirst(self::classify($word));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Version.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Version.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Common/Version.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Class to store and retrieve the version of Doctrine
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Version
+{
+    /**
+     * Current Doctrine Version
+     */
+    const VERSION = '2.2.2';
+
+    /**
+     * Compares a Doctrine version with the current one.
+     *
+     * @param string $version Doctrine version to compare.
+     * @return int Returns -1 if older, 0 if it is the same, 1 if version
+     *             passed as argument is newer.
+     */
+    public static function compare($version)
+    {
+        $currentVersion = str_replace(' ', '', strtolower(self::VERSION));
+        $version = str_replace(' ', '', $version);
+
+        return version_compare($version, $currentVersion);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ArrayStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ArrayStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ArrayStatement.php	(revision 345)
@@ -0,0 +1,94 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\DBAL\Driver\ResultStatement;
+use PDO;
+
+class ArrayStatement implements \IteratorAggregate, ResultStatement
+{
+    private $data;
+    private $columnCount = 0;
+    private $num = 0;
+    private $defaultFetchStyle = PDO::FETCH_BOTH;
+
+    public function __construct(array $data)
+    {
+        $this->data = $data;
+        if (count($data)) {
+            $this->columnCount = count($data[0]);
+        }
+    }
+
+    public function closeCursor()
+    {
+        unset ($this->data);
+    }
+
+    public function columnCount()
+    {
+        return $this->columnCount;
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        $this->defaultFetchStyle = $fetchStyle;
+    }
+
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        if (isset($this->data[$this->num])) {
+            $row = $this->data[$this->num++];
+            if ($fetchStyle === PDO::FETCH_ASSOC) {
+                return $row;
+            } else if ($fetchStyle === PDO::FETCH_NUM) {
+                return array_values($row);
+            } else if ($fetchStyle === PDO::FETCH_BOTH) {
+                return array_merge($row, array_values($row));
+            }
+        }
+        return false;
+    }
+
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (!isset($row[$columnIndex])) {
+            // TODO: verify this is correct behavior
+            return false;
+        }
+        return $row[$columnIndex];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/CacheException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/CacheException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/CacheException.php	(revision 345)
@@ -0,0 +1,37 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+/**
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.2
+ */
+class CacheException extends \Doctrine\DBAL\DBALException
+{
+    static public function noCacheKey()
+    {
+        return new self("No cache key was set.");
+    }
+
+    static public function noResultDriverConfigured()
+    {
+        return new self("Trying to cache a query but no result driver is configured.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/QueryCacheProfile.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/QueryCacheProfile.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/QueryCacheProfile.php	(revision 345)
@@ -0,0 +1,131 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * Query Cache Profile handles the data relevant for query caching.
+ *
+ * It is a value object, setter methods return NEW instances.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QueryCacheProfile
+{
+    /**
+     * @var Cache
+     */
+    private $resultCacheDriver;
+    /**
+     * @var int
+     */
+    private $lifetime = 0;
+    /**
+     * @var string
+     */
+    private $cacheKey;
+
+    /**
+     * @param int $lifetime
+     * @param string $cacheKey
+     * @param Cache $resultCache
+     */
+    public function __construct($lifetime = 0, $cacheKey = null, Cache $resultCache = null)
+    {
+        $this->lifetime = $lifetime;
+        $this->cacheKey = $cacheKey;
+        $this->resultCacheDriver = $resultCache;
+    }
+
+    /**
+     * @return Cache
+     */
+    public function getResultCacheDriver()
+    {
+        return $this->resultCacheDriver;
+    }
+
+    /**
+     * @return int
+     */
+    public function getLifetime()
+    {
+        return $this->lifetime;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        if ($this->cacheKey === null) {
+            throw CacheException::noCacheKey();
+        }
+        return $this->cacheKey;
+    }
+
+    /**
+     * Generate the real cache key from query, params and types.
+     *
+     * @param string $query
+     * @param array $params
+     * @param array $types
+     * @return array
+     */
+    public function generateCacheKeys($query, $params, $types)
+    {
+        $realCacheKey = $query . "-" . serialize($params) . "-" . serialize($types);
+        // should the key be automatically generated using the inputs or is the cache key set?
+        if ($this->cacheKey === null) {
+            $cacheKey = sha1($realCacheKey);
+        } else {
+            $cacheKey = $this->cacheKey;
+        }
+        return array($cacheKey, $realCacheKey);
+    }
+
+    /**
+     * @param Cache $cache
+     * @return QueryCacheProfile
+     */
+    public function setResultCacheDriver(Cache $cache)
+    {
+        return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
+    }
+
+    /**
+     * @param string|null $cacheKey
+     * @return QueryCacheProfile
+     */
+    public function setCacheKey($cacheKey)
+    {
+        return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver);
+    }
+
+    /**
+     * @param  int $lifetime
+     * @return QueryCacheProfile
+     */
+    public function setLifetime($lifetime)
+    {
+        return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ResultCacheStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ResultCacheStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Cache/ResultCacheStatement.php	(revision 345)
@@ -0,0 +1,255 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\DBAL\Driver\Statement;
+use Doctrine\DBAL\Driver\ResultStatement;
+use Doctrine\DBAL\Connection;
+use Doctrine\Common\Cache\Cache;
+use PDO;
+
+/**
+ * Cache statement for SQL results.
+ *
+ * A result is saved in multiple cache keys, there is the originally specified
+ * cache key which is just pointing to result rows by key. The following things
+ * have to be ensured:
+ *
+ * 1. lifetime of the original key has to be longer than that of all the individual rows keys
+ * 2. if any one row key is missing the query has to be re-executed.
+ *
+ * Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
+ * This means that the memory usage for cached results might increase by using this feature.
+ */
+class ResultCacheStatement implements \IteratorAggregate, ResultStatement
+{
+    /**
+     * @var \Doctrine\Common\Cache\Cache
+     */
+    private $resultCache;
+
+    /**
+     *
+     * @var string
+     */
+    private $cacheKey;
+
+    /**
+     * @var string
+     */
+    private $realKey;
+
+    /**
+     * @var int
+     */
+    private $lifetime;
+
+    /**
+     * @var Doctrine\DBAL\Driver\Statement
+     */
+    private $statement;
+
+    /**
+     * Did we reach the end of the statement?
+     *
+     * @var bool
+     */
+    private $emptied = false;
+
+    /**
+     * @var array
+     */
+    private $data;
+
+    /**
+     * @var int
+     */
+    private $defaultFetchStyle = PDO::FETCH_BOTH;
+
+    /**
+     * @param Statement $stmt
+     * @param Cache $resultCache
+     * @param string $cacheKey
+     * @param string $realKey
+     * @param int $lifetime
+     */
+    public function __construct(Statement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime)
+    {
+        $this->statement = $stmt;
+        $this->resultCache = $resultCache;
+        $this->cacheKey = $cacheKey;
+        $this->realKey = $realKey;
+        $this->lifetime = $lifetime;
+    }
+
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function closeCursor()
+    {
+        $this->statement->closeCursor();
+        if ($this->emptied && $this->data !== null) {
+            $data = $this->resultCache->fetch($this->cacheKey);
+            if (!$data) {
+                $data = array();
+            }
+            $data[$this->realKey] = $this->data;
+
+            $this->resultCache->save($this->cacheKey, $data, $this->lifetime);
+            unset($this->data);
+        }
+    }
+
+    /**
+     * columnCount
+     * Returns the number of columns in the result set
+     *
+     * @return integer              Returns the number of columns in the result set represented
+     *                              by the PDOStatement object. If there is no result set,
+     *                              this method should return 0.
+     */
+    public function columnCount()
+    {
+        return $this->statement->columnCount();
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        $this->defaultFetchStyle = $fetchStyle;
+    }
+
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * fetch
+     *
+     * @see Query::HYDRATE_* constants
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $cursorOrientation    For a PDOStatement object representing a scrollable cursor,
+     *                                      this value determines which row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
+     *                                      Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
+     *                                      PDOStatement object,
+     *                                      you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
+     *                                      prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
+     *
+     * @param integer $cursorOffset         For a PDOStatement object representing a scrollable cursor for which the
+     *                                      $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
+     *                                      the absolute number of the row in the result set that shall be fetched.
+     *
+     *                                      For a PDOStatement object representing a scrollable cursor for
+     *                                      which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
+     *                                      specifies the row to fetch relative to the cursor position before
+     *                                      PDOStatement->fetch() was called.
+     *
+     * @return mixed
+     */
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        if ($this->data === null) {
+            $this->data = array();
+        }
+
+        $row = $this->statement->fetch(PDO::FETCH_ASSOC);
+        if ($row) {
+            $this->data[] = $row;
+
+            if ($fetchStyle == PDO::FETCH_ASSOC) {
+                return $row;
+            } else if ($fetchStyle == PDO::FETCH_NUM) {
+                return array_values($row);
+            } else if ($fetchStyle == PDO::FETCH_BOTH) {
+                return array_merge($row, array_values($row));
+            } else {
+                throw new \InvalidArgumentException("Invalid fetch-style given for caching result.");
+            }
+        }
+        $this->emptied = true;
+        return false;
+    }
+
+    /**
+     * Returns an array containing all of the result set rows
+     *
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $columnIndex          Returns the indicated 0-indexed column when the value of $fetchStyle is
+     *                                      Query::HYDRATE_COLUMN. Defaults to 0.
+     *
+     * @return array
+     */
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    /**
+     * fetchColumn
+     * Returns a single column from the next row of a
+     * result set or FALSE if there are no more rows.
+     *
+     * @param integer $columnIndex          0-indexed number of the column you wish to retrieve from the row. If no
+     *                                      value is supplied, PDOStatement->fetchColumn()
+     *                                      fetches the first column.
+     *
+     * @return string                       returns a single column in the next row of a result set.
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (!isset($row[$columnIndex])) {
+            // TODO: verify this is correct behavior
+            return false;
+        }
+        return $row[$columnIndex];
+    }
+
+    /**
+     * rowCount
+     * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
+     * executed by the corresponding object.
+     *
+     * If the last SQL statement executed by the associated Statement object was a SELECT statement,
+     * some databases may return the number of rows returned by that statement. However,
+     * this behaviour is not guaranteed for all databases and should not be
+     * relied on for portable applications.
+     *
+     * @return integer                      Returns the number of rows.
+     */
+    public function rowCount()
+    {
+        return $this->statement->rowCount();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Configuration.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Configuration.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Configuration.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use Doctrine\DBAL\Logging\SQLLogger;
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * Configuration container for the Doctrine DBAL.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @internal When adding a new configuration option just write a getter/setter
+ *           pair and add the option to the _attributes array with a proper default value.
+ */
+class Configuration
+{
+    /**
+     * The attributes that are contained in the configuration.
+     * Values are default values.
+     *
+     * @var array
+     */
+    protected $_attributes = array();
+
+    /**
+     * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
+     *
+     * @param SQLLogger $logger
+     */
+    public function setSQLLogger(SQLLogger $logger = null)
+    {
+        $this->_attributes['sqlLogger'] = $logger;
+    }
+
+    /**
+     * Gets the SQL logger that is used.
+     *
+     * @return SQLLogger
+     */
+    public function getSQLLogger()
+    {
+        return isset($this->_attributes['sqlLogger']) ?
+                $this->_attributes['sqlLogger'] : null;
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for query result caching.
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getResultCacheImpl()
+    {
+        return isset($this->_attributes['resultCacheImpl']) ?
+                $this->_attributes['resultCacheImpl'] : null;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for query result caching.
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheImpl
+     */
+    public function setResultCacheImpl(Cache $cacheImpl)
+    {
+        $this->_attributes['resultCacheImpl'] = $cacheImpl;
+    }
+
+    /**
+     * Filter schema assets expression.
+     *
+     * Only include tables/sequences matching the filter expression regexp in
+     * schema instances generated for the active connection when calling
+     * {AbstractSchemaManager#createSchema()}.
+     *
+     * @param string $filterExpression
+     */
+    public function setFilterSchemaAssetsExpression($filterExpression)
+    {
+        $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
+    }
+
+    /**
+     * Return filter schema assets expression.
+     *
+     * @return string|null
+     */
+    public function getFilterSchemaAssetsExpression()
+    {
+        if (isset($this->_attributes['filterSchemaAssetsExpression'])) {
+            return $this->_attributes['filterSchemaAssetsExpression'];
+        }
+        return null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connection.php	(revision 345)
@@ -0,0 +1,1168 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use PDO, Closure, Exception,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Driver\Connection as DriverConnection,
+    Doctrine\Common\EventManager,
+    Doctrine\DBAL\DBALException,
+    Doctrine\DBAL\Cache\ResultCacheStatement,
+    Doctrine\DBAL\Cache\QueryCacheProfile,
+    Doctrine\DBAL\Cache\ArrayStatement,
+    Doctrine\DBAL\Cache\CacheException;
+
+/**
+ * A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like
+ * events, transaction isolation levels, configuration, emulated transaction nesting,
+ * lazy connecting and more.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author  Lukas Smith <smith@pooteeweet.org> (MDB2 library)
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Connection implements DriverConnection
+{
+    /**
+     * Constant for transaction isolation level READ UNCOMMITTED.
+     */
+    const TRANSACTION_READ_UNCOMMITTED = 1;
+
+    /**
+     * Constant for transaction isolation level READ COMMITTED.
+     */
+    const TRANSACTION_READ_COMMITTED = 2;
+
+    /**
+     * Constant for transaction isolation level REPEATABLE READ.
+     */
+    const TRANSACTION_REPEATABLE_READ = 3;
+
+    /**
+     * Constant for transaction isolation level SERIALIZABLE.
+     */
+    const TRANSACTION_SERIALIZABLE = 4;
+
+    /**
+     * Represents an array of ints to be expanded by Doctrine SQL parsing.
+     *
+     * @var int
+     */
+    const PARAM_INT_ARRAY = 101;
+
+    /**
+     * Represents an array of strings to be expanded by Doctrine SQL parsing.
+     *
+     * @var int
+     */
+    const PARAM_STR_ARRAY = 102;
+
+    /**
+     * Offset by which PARAM_* constants are detected as arrays of the param type.
+     *
+     * @var int
+     */
+    const ARRAY_PARAM_OFFSET = 100;
+
+    /**
+     * The wrapped driver connection.
+     *
+     * @var Doctrine\DBAL\Driver\Connection
+     */
+    protected $_conn;
+
+    /**
+     * @var Doctrine\DBAL\Configuration
+     */
+    protected $_config;
+
+    /**
+     * @var Doctrine\Common\EventManager
+     */
+    protected $_eventManager;
+
+    /**
+     * @var Doctrine\DBAL\Query\ExpressionBuilder
+     */
+    protected $_expr;
+
+    /**
+     * Whether or not a connection has been established.
+     *
+     * @var boolean
+     */
+    private $_isConnected = false;
+
+    /**
+     * The transaction nesting level.
+     *
+     * @var integer
+     */
+    private $_transactionNestingLevel = 0;
+
+    /**
+     * The currently active transaction isolation level.
+     *
+     * @var integer
+     */
+    private $_transactionIsolationLevel;
+
+    /**
+     * If nested transations should use savepoints
+     *
+     * @var integer
+     */
+    private $_nestTransactionsWithSavepoints;
+
+    /**
+     * The parameters used during creation of the Connection instance.
+     *
+     * @var array
+     */
+    private $_params = array();
+
+    /**
+     * The DatabasePlatform object that provides information about the
+     * database platform used by the connection.
+     *
+     * @var Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    protected $_platform;
+
+    /**
+     * The schema manager.
+     *
+     * @var Doctrine\DBAL\Schema\SchemaManager
+     */
+    protected $_schemaManager;
+
+    /**
+     * The used DBAL driver.
+     *
+     * @var Doctrine\DBAL\Driver
+     */
+    protected $_driver;
+
+    /**
+     * Flag that indicates whether the current transaction is marked for rollback only.
+     *
+     * @var boolean
+     */
+    private $_isRollbackOnly = false;
+
+    /**
+     * Initializes a new instance of the Connection class.
+     *
+     * @param array $params  The connection parameters.
+     * @param Driver $driver
+     * @param Configuration $config
+     * @param EventManager $eventManager
+     */
+    public function __construct(array $params, Driver $driver, Configuration $config = null,
+            EventManager $eventManager = null)
+    {
+        $this->_driver = $driver;
+        $this->_params = $params;
+
+        if (isset($params['pdo'])) {
+            $this->_conn = $params['pdo'];
+            $this->_isConnected = true;
+        }
+
+        // Create default config and event manager if none given
+        if ( ! $config) {
+            $config = new Configuration();
+        }
+
+        if ( ! $eventManager) {
+            $eventManager = new EventManager();
+        }
+
+        $this->_config = $config;
+        $this->_eventManager = $eventManager;
+
+        $this->_expr = new Query\Expression\ExpressionBuilder($this);
+
+        if ( ! isset($params['platform'])) {
+            $this->_platform = $driver->getDatabasePlatform();
+        } else if ($params['platform'] instanceof Platforms\AbstractPlatform) {
+            $this->_platform = $params['platform'];
+        } else {
+            throw DBALException::invalidPlatformSpecified();
+        }
+
+        $this->_platform->setEventManager($eventManager);
+
+        $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
+    }
+
+    /**
+     * Gets the parameters used during instantiation.
+     *
+     * @return array $params
+     */
+    public function getParams()
+    {
+        return $this->_params;
+    }
+
+    /**
+     * Gets the name of the database this Connection is connected to.
+     *
+     * @return string $database
+     */
+    public function getDatabase()
+    {
+        return $this->_driver->getDatabase($this);
+    }
+
+    /**
+     * Gets the hostname of the currently connected database.
+     *
+     * @return string
+     */
+    public function getHost()
+    {
+        return isset($this->_params['host']) ? $this->_params['host'] : null;
+    }
+
+    /**
+     * Gets the port of the currently connected database.
+     *
+     * @return mixed
+     */
+    public function getPort()
+    {
+        return isset($this->_params['port']) ? $this->_params['port'] : null;
+    }
+
+    /**
+     * Gets the username used by this connection.
+     *
+     * @return string
+     */
+    public function getUsername()
+    {
+        return isset($this->_params['user']) ? $this->_params['user'] : null;
+    }
+
+    /**
+     * Gets the password used by this connection.
+     *
+     * @return string
+     */
+    public function getPassword()
+    {
+        return isset($this->_params['password']) ? $this->_params['password'] : null;
+    }
+
+    /**
+     * Gets the DBAL driver instance.
+     *
+     * @return \Doctrine\DBAL\Driver
+     */
+    public function getDriver()
+    {
+        return $this->_driver;
+    }
+
+    /**
+     * Gets the Configuration used by the Connection.
+     *
+     * @return \Doctrine\DBAL\Configuration
+     */
+    public function getConfiguration()
+    {
+        return $this->_config;
+    }
+
+    /**
+     * Gets the EventManager used by the Connection.
+     *
+     * @return \Doctrine\Common\EventManager
+     */
+    public function getEventManager()
+    {
+        return $this->_eventManager;
+    }
+
+    /**
+     * Gets the DatabasePlatform for the connection.
+     *
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * Gets the ExpressionBuilder for the connection.
+     *
+     * @return \Doctrine\DBAL\Query\ExpressionBuilder
+     */
+    public function getExpressionBuilder()
+    {
+        return $this->_expr;
+    }
+
+    /**
+     * Establishes the connection with the database.
+     *
+     * @return boolean TRUE if the connection was successfully established, FALSE if
+     *                 the connection is already open.
+     */
+    public function connect()
+    {
+        if ($this->_isConnected) return false;
+
+        $driverOptions = isset($this->_params['driverOptions']) ?
+                $this->_params['driverOptions'] : array();
+        $user = isset($this->_params['user']) ? $this->_params['user'] : null;
+        $password = isset($this->_params['password']) ?
+                $this->_params['password'] : null;
+
+        $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
+        $this->_isConnected = true;
+
+        if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            $eventArgs = new Event\ConnectionEventArgs($this);
+            $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the first row of the result
+     * as an associative array.
+     *
+     * @param string $statement The SQL query.
+     * @param array $params The query parameters.
+     * @return array
+     */
+    public function fetchAssoc($statement, array $params = array())
+    {
+        return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_ASSOC);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the first row of the result
+     * as a numerically indexed array.
+     *
+     * @param string $statement         sql query to be executed
+     * @param array $params             prepared statement params
+     * @return array
+     */
+    public function fetchArray($statement, array $params = array())
+    {
+        return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_NUM);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the value of a single column
+     * of the first row of the result.
+     *
+     * @param string $statement         sql query to be executed
+     * @param array $params             prepared statement params
+     * @param int $colnum               0-indexed column number to retrieve
+     * @return mixed
+     */
+    public function fetchColumn($statement, array $params = array(), $colnum = 0)
+    {
+        return $this->executeQuery($statement, $params)->fetchColumn($colnum);
+    }
+
+    /**
+     * Whether an actual connection to the database is established.
+     *
+     * @return boolean
+     */
+    public function isConnected()
+    {
+        return $this->_isConnected;
+    }
+
+    /**
+     * Checks whether a transaction is currently active.
+     *
+     * @return boolean TRUE if a transaction is currently active, FALSE otherwise.
+     */
+    public function isTransactionActive()
+    {
+        return $this->_transactionNestingLevel > 0;
+    }
+
+    /**
+     * Executes an SQL DELETE statement on a table.
+     *
+     * @param string $table The name of the table on which to delete.
+     * @param array $identifier The deletion criteria. An associateve array containing column-value pairs.
+     * @return integer The number of affected rows.
+     */
+    public function delete($tableName, array $identifier)
+    {
+        $this->connect();
+
+        $criteria = array();
+
+        foreach (array_keys($identifier) as $columnName) {
+            $criteria[] = $columnName . ' = ?';
+        }
+
+        $query = 'DELETE FROM ' . $tableName . ' WHERE ' . implode(' AND ', $criteria);
+
+        return $this->executeUpdate($query, array_values($identifier));
+    }
+
+    /**
+     * Closes the connection.
+     *
+     * @return void
+     */
+    public function close()
+    {
+        unset($this->_conn);
+
+        $this->_isConnected = false;
+    }
+
+    /**
+     * Sets the transaction isolation level.
+     *
+     * @param integer $level The level to set.
+     */
+    public function setTransactionIsolation($level)
+    {
+        $this->_transactionIsolationLevel = $level;
+
+        return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
+    }
+
+    /**
+     * Gets the currently active transaction isolation level.
+     *
+     * @return integer The current transaction isolation level.
+     */
+    public function getTransactionIsolation()
+    {
+        return $this->_transactionIsolationLevel;
+    }
+
+    /**
+     * Executes an SQL UPDATE statement on a table.
+     *
+     * @param string $table The name of the table to update.
+     * @param array $identifier The update criteria. An associative array containing column-value pairs.
+     * @param array $types Types of the merged $data and $identifier arrays in that order.
+     * @return integer The number of affected rows.
+     */
+    public function update($tableName, array $data, array $identifier, array $types = array())
+    {
+        $this->connect();
+        $set = array();
+        foreach ($data as $columnName => $value) {
+            $set[] = $columnName . ' = ?';
+        }
+
+        $params = array_merge(array_values($data), array_values($identifier));
+
+        $sql  = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $set)
+                . ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
+                . ' = ?';
+
+        return $this->executeUpdate($sql, $params, $types);
+    }
+
+    /**
+     * Inserts a table row with specified data.
+     *
+     * @param string $table The name of the table to insert data into.
+     * @param array $data An associative array containing column-value pairs.
+     * @param array $types Types of the inserted data.
+     * @return integer The number of affected rows.
+     */
+    public function insert($tableName, array $data, array $types = array())
+    {
+        $this->connect();
+
+        // column names are specified as array keys
+        $cols = array();
+        $placeholders = array();
+
+        foreach ($data as $columnName => $value) {
+            $cols[] = $columnName;
+            $placeholders[] = '?';
+        }
+
+        $query = 'INSERT INTO ' . $tableName
+               . ' (' . implode(', ', $cols) . ')'
+               . ' VALUES (' . implode(', ', $placeholders) . ')';
+
+        return $this->executeUpdate($query, array_values($data), $types);
+    }
+
+    /**
+     * Sets the given charset on the current connection.
+     *
+     * @param string $charset The charset to set.
+     */
+    public function setCharset($charset)
+    {
+        $this->executeUpdate($this->_platform->getSetCharsetSQL($charset));
+    }
+
+    /**
+     * Quote a string so it can be safely used as a table or column name, even if
+     * it is a reserved name.
+     *
+     * Delimiting style depends on the underlying database platform that is being used.
+     *
+     * NOTE: Just because you CAN use quoted identifiers does not mean
+     * you SHOULD use them. In general, they end up causing way more
+     * problems than they solve.
+     *
+     * @param string $str The name to be quoted.
+     * @return string The quoted name.
+     */
+    public function quoteIdentifier($str)
+    {
+        return $this->_platform->quoteIdentifier($str);
+    }
+
+    /**
+     * Quotes a given input parameter.
+     *
+     * @param mixed $input Parameter to be quoted.
+     * @param string $type Type of the parameter.
+     * @return string The quoted parameter.
+     */
+    public function quote($input, $type = null)
+    {
+        $this->connect();
+
+        list($value, $bindingType) = $this->getBindingInfo($input, $type);
+        return $this->_conn->quote($value, $bindingType);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the result as an associative array.
+     *
+     * @param string $sql The SQL query.
+     * @param array $params The query parameters.
+     * @return array
+     */
+    public function fetchAll($sql, array $params = array())
+    {
+        return $this->executeQuery($sql, $params)->fetchAll(PDO::FETCH_ASSOC);
+    }
+
+    /**
+     * Prepares an SQL statement.
+     *
+     * @param string $statement The SQL statement to prepare.
+     * @return Doctrine\DBAL\Driver\Statement The prepared statement.
+     */
+    public function prepare($statement)
+    {
+        $this->connect();
+
+        return new Statement($statement, $this);
+    }
+
+    /**
+     * Executes an, optionally parameterized, SQL query.
+     *
+     * If the query is parameterized, a prepared statement is used.
+     * If an SQLLogger is configured, the execution is logged.
+     *
+     * @param string $query The SQL query to execute.
+     * @param array $params The parameters to bind to the query, if any.
+     * @param array $types The types the previous parameters are in.
+     * @param QueryCacheProfile $qcp
+     * @return Doctrine\DBAL\Driver\Statement The executed statement.
+     * @internal PERF: Directly prepares a driver statement, not a wrapper.
+     */
+    public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
+    {
+        if ($qcp !== null) {
+            return $this->executeCacheQuery($query, $params, $types, $qcp);
+        }
+
+        $this->connect();
+
+        $hasLogger = $this->_config->getSQLLogger() !== null;
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->startQuery($query, $params, $types);
+        }
+
+        if ($params) {
+            list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
+
+            $stmt = $this->_conn->prepare($query);
+            if ($types) {
+                $this->_bindTypedValues($stmt, $params, $types);
+                $stmt->execute();
+            } else {
+                $stmt->execute($params);
+            }
+        } else {
+            $stmt = $this->_conn->query($query);
+        }
+
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->stopQuery();
+        }
+
+        return $stmt;
+    }
+
+    /**
+     * Execute a caching query and
+     *
+     * @param string $query
+     * @param array $params
+     * @param array $types
+     * @param QueryCacheProfile $qcp
+     * @return \Doctrine\DBAL\Driver\ResultStatement
+     */
+    public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp)
+    {
+        $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl();
+        if (!$resultCache) {
+            throw CacheException::noResultDriverConfigured();
+        }
+
+        list($cacheKey, $realKey) = $qcp->generateCacheKeys($query, $params, $types);
+
+        // fetch the row pointers entry
+        if ($data = $resultCache->fetch($cacheKey)) {
+            // is the real key part of this row pointers map or is the cache only pointing to other cache keys?
+            if (isset($data[$realKey])) {
+                return new ArrayStatement($data[$realKey]);
+            } else if (array_key_exists($realKey, $data)) {
+                return new ArrayStatement(array());
+            }
+        }
+        return new ResultCacheStatement($this->executeQuery($query, $params, $types), $resultCache, $cacheKey, $realKey, $qcp->getLifetime());
+    }
+
+    /**
+     * Executes an, optionally parameterized, SQL query and returns the result,
+     * applying a given projection/transformation function on each row of the result.
+     *
+     * @param string $query The SQL query to execute.
+     * @param array $params The parameters, if any.
+     * @param Closure $mapper The transformation function that is applied on each row.
+     *                        The function receives a single paramater, an array, that
+     *                        represents a row of the result set.
+     * @return mixed The projected result of the query.
+     */
+    public function project($query, array $params, Closure $function)
+    {
+        $result = array();
+        $stmt = $this->executeQuery($query, $params ?: array());
+
+        while ($row = $stmt->fetch()) {
+            $result[] = $function($row);
+        }
+
+        $stmt->closeCursor();
+
+        return $result;
+    }
+
+    /**
+     * Executes an SQL statement, returning a result set as a Statement object.
+     *
+     * @param string $statement
+     * @param integer $fetchType
+     * @return Doctrine\DBAL\Driver\Statement
+     */
+    public function query()
+    {
+        $this->connect();
+
+        $args = func_get_args();
+
+        $logger = $this->getConfiguration()->getSQLLogger();
+        if ($logger) {
+            $logger->startQuery($args[0]);
+        }
+
+        $statement = call_user_func_array(array($this->_conn, 'query'), $args);
+
+        if ($logger) {
+            $logger->stopQuery();
+        }
+
+        return $statement;
+    }
+
+    /**
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
+     * and returns the number of affected rows.
+     *
+     * This method supports PDO binding types as well as DBAL mapping types.
+     *
+     * @param string $query The SQL query.
+     * @param array $params The query parameters.
+     * @param array $types The parameter types.
+     * @return integer The number of affected rows.
+     * @internal PERF: Directly prepares a driver statement, not a wrapper.
+     */
+    public function executeUpdate($query, array $params = array(), array $types = array())
+    {
+        $this->connect();
+
+        $hasLogger = $this->_config->getSQLLogger() !== null;
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->startQuery($query, $params, $types);
+        }
+
+        if ($params) {
+            list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
+
+            $stmt = $this->_conn->prepare($query);
+            if ($types) {
+                $this->_bindTypedValues($stmt, $params, $types);
+                $stmt->execute();
+            } else {
+                $stmt->execute($params);
+            }
+            $result = $stmt->rowCount();
+        } else {
+            $result = $this->_conn->exec($query);
+        }
+
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->stopQuery();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Execute an SQL statement and return the number of affected rows.
+     *
+     * @param string $statement
+     * @return integer The number of affected rows.
+     */
+    public function exec($statement)
+    {
+        $this->connect();
+        return $this->_conn->exec($statement);
+    }
+
+    /**
+     * Returns the current transaction nesting level.
+     *
+     * @return integer The nesting level. A value of 0 means there's no active transaction.
+     */
+    public function getTransactionNestingLevel()
+    {
+        return $this->_transactionNestingLevel;
+    }
+
+    /**
+     * Fetch the SQLSTATE associated with the last database operation.
+     *
+     * @return integer The last error code.
+     */
+    public function errorCode()
+    {
+        $this->connect();
+        return $this->_conn->errorCode();
+    }
+
+    /**
+     * Fetch extended error information associated with the last database operation.
+     *
+     * @return array The last error information.
+     */
+    public function errorInfo()
+    {
+        $this->connect();
+        return $this->_conn->errorInfo();
+    }
+
+    /**
+     * Returns the ID of the last inserted row, or the last value from a sequence object,
+     * depending on the underlying driver.
+     *
+     * Note: This method may not return a meaningful or consistent result across different drivers,
+     * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
+     * columns or sequences.
+     *
+     * @param string $seqName Name of the sequence object from which the ID should be returned.
+     * @return string A string representation of the last inserted ID.
+     */
+    public function lastInsertId($seqName = null)
+    {
+        $this->connect();
+        return $this->_conn->lastInsertId($seqName);
+    }
+
+    /**
+     * Executes a function in a transaction.
+     *
+     * The function gets passed this Connection instance as an (optional) parameter.
+     *
+     * If an exception occurs during execution of the function or transaction commit,
+     * the transaction is rolled back and the exception re-thrown.
+     *
+     * @param Closure $func The function to execute transactionally.
+     */
+    public function transactional(Closure $func)
+    {
+        $this->beginTransaction();
+        try {
+            $func($this);
+            $this->commit();
+        } catch (Exception $e) {
+            $this->rollback();
+            throw $e;
+        }
+    }
+
+    /**
+     * Set if nested transactions should use savepoints
+     *
+     * @param boolean
+     * @return void
+     */
+    public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints)
+    {
+        if ($this->_transactionNestingLevel > 0) {
+            throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
+        }
+
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_nestTransactionsWithSavepoints = $nestTransactionsWithSavepoints;
+    }
+
+    /**
+     * Get if nested transactions should use savepoints
+     *
+     * @return boolean
+     */
+    public function getNestTransactionsWithSavepoints()
+    {
+        return $this->_nestTransactionsWithSavepoints;
+    }
+
+    /**
+     * Returns the savepoint name to use for nested transactions are false if they are not supported
+     * "savepointFormat" parameter is not set
+     *
+     * @return mixed a string with the savepoint name or false
+     */
+    protected function _getNestedTransactionSavePointName()
+    {
+        return 'DOCTRINE2_SAVEPOINT_'.$this->_transactionNestingLevel;
+    }
+
+    /**
+     * Starts a transaction by suspending auto-commit mode.
+     *
+     * @return void
+     */
+    public function beginTransaction()
+    {
+        $this->connect();
+
+        ++$this->_transactionNestingLevel;
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_conn->beginTransaction();
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->createSavepoint($this->_getNestedTransactionSavePointName());
+        }
+    }
+
+    /**
+     * Commits the current transaction.
+     *
+     * @return void
+     * @throws ConnectionException If the commit failed due to no active transaction or
+     *                             because the transaction was marked for rollback only.
+     */
+    public function commit()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        if ($this->_isRollbackOnly) {
+            throw ConnectionException::commitFailedRollbackOnly();
+        }
+
+        $this->connect();
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_conn->commit();
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->releaseSavepoint($this->_getNestedTransactionSavePointName());
+        }
+
+        --$this->_transactionNestingLevel;
+    }
+
+    /**
+     * Cancel any database changes done during the current transaction.
+     *
+     * this method can be listened with onPreTransactionRollback and onTransactionRollback
+     * eventlistener methods
+     *
+     * @throws ConnectionException If the rollback operation failed.
+     */
+    public function rollback()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+
+        $this->connect();
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_transactionNestingLevel = 0;
+            $this->_conn->rollback();
+            $this->_isRollbackOnly = false;
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->rollbackSavepoint($this->_getNestedTransactionSavePointName());
+            --$this->_transactionNestingLevel;
+        } else {
+            $this->_isRollbackOnly = true;
+            --$this->_transactionNestingLevel;
+        }
+    }
+
+    /**
+     * createSavepoint
+     * creates a new savepoint
+     *
+     * @param string $savepoint     name of a savepoint to set
+     * @return void
+     */
+    public function createSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_conn->exec($this->_platform->createSavePoint($savepoint));
+    }
+
+    /**
+     * releaseSavePoint
+     * releases given savepoint
+     *
+     * @param string $savepoint     name of a savepoint to release
+     * @return void
+     */
+    public function releaseSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        if ($this->_platform->supportsReleaseSavepoints()) {
+            $this->_conn->exec($this->_platform->releaseSavePoint($savepoint));
+        }
+    }
+
+    /**
+     * rollbackSavePoint
+     * releases given savepoint
+     *
+     * @param string $savepoint     name of a savepoint to rollback to
+     * @return void
+     */
+    public function rollbackSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_conn->exec($this->_platform->rollbackSavePoint($savepoint));
+    }
+
+    /**
+     * Gets the wrapped driver connection.
+     *
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function getWrappedConnection()
+    {
+        $this->connect();
+
+        return $this->_conn;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect or change the
+     * database schema through the connection.
+     *
+     * @return Doctrine\DBAL\Schema\AbstractSchemaManager
+     */
+    public function getSchemaManager()
+    {
+        if ( ! $this->_schemaManager) {
+            $this->_schemaManager = $this->_driver->getSchemaManager($this);
+        }
+
+        return $this->_schemaManager;
+    }
+
+    /**
+     * Marks the current transaction so that the only possible
+     * outcome for the transaction to be rolled back.
+     *
+     * @throws ConnectionException If no transaction is active.
+     */
+    public function setRollbackOnly()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        $this->_isRollbackOnly = true;
+    }
+
+    /**
+     * Check whether the current transaction is marked for rollback only.
+     *
+     * @return boolean
+     * @throws ConnectionException If no transaction is active.
+     */
+    public function isRollbackOnly()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        return $this->_isRollbackOnly;
+    }
+
+    /**
+     * Converts a given value to its database representation according to the conversion
+     * rules of a specific DBAL mapping type.
+     *
+     * @param mixed $value The value to convert.
+     * @param string $type The name of the DBAL mapping type.
+     * @return mixed The converted value.
+     */
+    public function convertToDatabaseValue($value, $type)
+    {
+        return Type::getType($type)->convertToDatabaseValue($value, $this->_platform);
+    }
+
+    /**
+     * Converts a given value to its PHP representation according to the conversion
+     * rules of a specific DBAL mapping type.
+     *
+     * @param mixed $value The value to convert.
+     * @param string $type The name of the DBAL mapping type.
+     * @return mixed The converted type.
+     */
+    public function convertToPHPValue($value, $type)
+    {
+        return Type::getType($type)->convertToPHPValue($value, $this->_platform);
+    }
+
+    /**
+     * Binds a set of parameters, some or all of which are typed with a PDO binding type
+     * or DBAL mapping type, to a given statement.
+     *
+     * @param $stmt The statement to bind the values to.
+     * @param array $params The map/list of named/positional parameters.
+     * @param array $types The parameter types (PDO binding types or DBAL mapping types).
+     * @internal Duck-typing used on the $stmt parameter to support driver statements as well as
+     *           raw PDOStatement instances.
+     */
+    private function _bindTypedValues($stmt, array $params, array $types)
+    {
+        // Check whether parameters are positional or named. Mixing is not allowed, just like in PDO.
+        if (is_int(key($params))) {
+            // Positional parameters
+            $typeOffset = array_key_exists(0, $types) ? -1 : 0;
+            $bindIndex = 1;
+            foreach ($params as $position => $value) {
+                $typeIndex = $bindIndex + $typeOffset;
+                if (isset($types[$typeIndex])) {
+                    $type = $types[$typeIndex];
+                    list($value, $bindingType) = $this->getBindingInfo($value, $type);
+                    $stmt->bindValue($bindIndex, $value, $bindingType);
+                } else {
+                    $stmt->bindValue($bindIndex, $value);
+                }
+                ++$bindIndex;
+            }
+        } else {
+            // Named parameters
+            foreach ($params as $name => $value) {
+                if (isset($types[$name])) {
+                    $type = $types[$name];
+                    list($value, $bindingType) = $this->getBindingInfo($value, $type);
+                    $stmt->bindValue($name, $value, $bindingType);
+                } else {
+                    $stmt->bindValue($name, $value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type.
+     *
+     * @param mixed $value The value to bind
+     * @param mixed $type The type to bind (PDO or DBAL)
+     * @return array [0] => the (escaped) value, [1] => the binding type
+     */
+    private function getBindingInfo($value, $type)
+    {
+        if (is_string($type)) {
+            $type = Type::getType($type);
+        }
+        if ($type instanceof Type) {
+            $value = $type->convertToDatabaseValue($value, $this->_platform);
+            $bindingType = $type->getBindingType();
+        } else {
+            $bindingType = $type; // PDO::PARAM_* constants
+        }
+        return array($value, $bindingType);
+    }
+
+    /**
+     * Create a new instance of a SQL query builder.
+     *
+     * @return Query\QueryBuilder
+     */
+    public function createQueryBuilder()
+    {
+        return new Query\QueryBuilder($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/ConnectionException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/ConnectionException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/ConnectionException.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id: Exception.php 4628 2008-07-04 16:32:19Z romanb $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Doctrine\DBAL\ConnectionException
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @version     $Revision: 4628 $
+ * @author      Jonathan H. Wage <jonwage@gmail.com
+ */
+class ConnectionException extends DBALException
+{
+    public static function commitFailedRollbackOnly()
+    {
+        return new self("Transaction commit failed because the transaction has been marked for rollback only.");
+    }
+
+    public static function noActiveTransaction()
+    {
+        return new self("There is no active transaction.");
+    }
+
+    public static function savepointsNotSupported()
+    {
+        return new self("Savepoints are not supported by this driver.");
+    }
+
+    public static function mayNotAlterNestedTransactionWithSavepointsInTransaction()
+    {
+        return new self("May not alter the nested transaction with savepoints behavior while a transaction is open.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connections/MasterSlaveConnection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connections/MasterSlaveConnection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Connections/MasterSlaveConnection.php	(revision 345)
@@ -0,0 +1,328 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Connections;
+
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Driver,
+    Doctrine\DBAL\Configuration,
+    Doctrine\Common\EventManager,
+    Doctrine\DBAL\Events;
+
+/**
+ * Master-Slave Connection
+ *
+ * Connection can be used with master-slave setups.
+ *
+ * Important for the understanding of this connection should be how and when
+ * it picks the slave or master.
+ *
+ * 1. Slave if master was never picked before and ONLY if 'getWrappedConnection'
+ *    or 'executeQuery' is used.
+ * 2. Master picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint',
+ *    'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or
+ *    'prepare' is called.
+ * 3. If master was picked once during the lifetime of the connection it will always get picked afterwards.
+ * 4. One slave connection is randomly picked ONCE during a request.
+ *
+ * ATTENTION: You can write to the slave with this connection if you execute a write query without
+ * opening up a transaction. For example:
+ *
+ *      $conn = DriverManager::getConnection(...);
+ *      $conn->executeQuery("DELETE FROM table");
+ *
+ * Be aware that Connection#executeQuery is a method specifically for READ
+ * operations only.
+ *
+ * This connection is limited to slave operations using the
+ * Connection#executeQuery operation only, because it wouldn't be compatible
+ * with the ORM or SchemaManager code otherwise. Both use all the other
+ * operations in a context where writes could happen to a slave, which makes
+ * this restricted approach necessary.
+ *
+ * You can manually connect to the master at any time by calling:
+ *
+ *      $conn->connect('master');
+ *
+ * Instantiation through the DriverManager looks like:
+ *
+ * @example
+ *
+ * $conn = DriverManager::getConnection(array(
+ *    'wrapperClass' => 'Doctrine\DBAL\Connections\MasterSlaveConnection',
+ *    'driver' => 'pdo_mysql',
+ *    'master' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''),
+ *    'slaves' => array(
+ *        array('user' => 'slave1', 'password', 'host' => '', 'dbname' => ''),
+ *        array('user' => 'slave2', 'password', 'host' => '', 'dbname' => ''),
+ *    )
+ * ));
+ *
+ * You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information.
+ *
+ * @author Lars Strojny <lstrojny@php.net>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class MasterSlaveConnection extends Connection
+{
+    /**
+     * Master and slave connection (one of the randomly picked slaves)
+     *
+     * @var Doctrine\DBAL\Driver\Connection[]
+     */
+    protected $connections = array('master' => null, 'slave' => null);
+
+    /**
+     * Create Master Slave Connection
+     *
+     * @param array $params
+     * @param Driver $driver
+     * @param Configuration $config
+     * @param EventManager $eventManager
+     */
+    public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null)
+    {
+        if ( !isset($params['slaves']) || !isset($params['master']) ) {
+            throw new \InvalidArgumentException('master or slaves configuration missing');
+        }
+        if ( count($params['slaves']) == 0 ) {
+            throw new \InvalidArgumentException('You have to configure at least one slaves.');
+        }
+
+        $params['master']['driver'] = $params['driver'];
+        foreach ($params['slaves'] as $slaveKey => $slave) {
+            $params['slaves'][$slaveKey]['driver'] = $params['driver'];
+        }
+
+        parent::__construct($params, $driver, $config, $eventManager);
+    }
+
+    /**
+     * Check if the connection is currently towards the master or not.
+     *
+     * @return bool
+     */
+    public function isConnectedToMaster()
+    {
+        return $this->_conn !== null && $this->_conn === $this->connections['master'];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function connect($connectionName = 'slave')
+    {
+        if ( $connectionName !== 'slave' && $connectionName !== 'master' ) {
+            throw new \InvalidArgumentException("Invalid option to connect(), only master or slave allowed.");
+        }
+
+        $forceMasterAsSlave = false;
+
+        if ($this->getTransactionNestingLevel() > 0) {
+            $connectionName = 'master';
+            $forceMasterAsSlave = true;
+        }
+
+        if ($this->connections[$connectionName]) {
+            if ($forceMasterAsSlave) {
+                $this->connections['slave'] = $this->_conn = $this->connections['master'];
+            } else {
+                $this->_conn = $this->connections[$connectionName];
+            }
+            return false;
+        }
+
+        if ($connectionName === 'master') {
+            /** Set slave connection to master to avoid invalid reads */
+            if ($this->connections['slave']) {
+                unset($this->connections['slave']);
+            }
+
+            $this->connections['master'] = $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName);
+        } else {
+            $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName);
+        }
+
+        if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            $eventArgs = new Event\ConnectionEventArgs($this);
+            $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
+        }
+
+        return true;
+    }
+
+    /**
+     * Connect to a specific connection
+     *
+     * @param  string $connectionName
+     * @return Driver
+     */
+    protected function connectTo($connectionName)
+    {
+        $params = $this->getParams();
+
+        $driverOptions = isset($params['driverOptions']) ? $params['driverOptions'] : array();
+
+        $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params);
+
+        $user = isset($connectionParams['user']) ? $connectionParams['user'] : null;
+        $password = isset($connectionParams['password']) ? $connectionParams['password'] : null;
+
+        return $this->_driver->connect($connectionParams, $user, $password, $driverOptions);
+    }
+
+    protected function chooseConnectionConfiguration($connectionName, $params)
+    {
+        if ($connectionName === 'master') {
+            return $params['master'];
+        }
+
+        return $params['slaves'][array_rand($params['slaves'])];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function executeUpdate($query, array $params = array(), array $types = array())
+    {
+        $this->connect('master');
+        return parent::executeUpdate($query, $params, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function beginTransaction()
+    {
+        $this->connect('master');
+        return parent::beginTransaction();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function commit()
+    {
+        $this->connect('master');
+        return parent::commit();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function rollback()
+    {
+        $this->connect('master');
+        return parent::rollback();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function delete($tableName, array $identifier)
+    {
+        $this->connect('master');
+        return parent::delete($tableName, $identifier);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function update($tableName, array $data, array $identifier, array $types = array())
+    {
+        $this->connect('master');
+        return parent::update($tableName, $data, $identifier, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function insert($tableName, array $data, array $types = array())
+    {
+        $this->connect('master');
+        return parent::insert($tableName, $data, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function exec($statement)
+    {
+        $this->connect('master');
+        return parent::exec($statement);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function createSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::createSavepoint($savepoint);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function releaseSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::releaseSavepoint($savepoint);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function rollbackSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::rollbackSavepoint($savepoint);
+    }
+
+    public function query()
+    {
+        $this->connect('master');
+
+        $args = func_get_args();
+
+        $logger = $this->getConfiguration()->getSQLLogger();
+        if ($logger) {
+            $logger->startQuery($args[0]);
+        }
+
+        $statement = call_user_func_array(array($this->_conn, 'query'), $args);
+
+        if ($logger) {
+            $logger->stopQuery();
+        }
+
+        return $statement;
+    }
+
+    public function prepare($statement)
+    {
+        $this->connect('master');
+
+        return parent::prepare($statement);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DBALException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DBALException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DBALException.php	(revision 345)
@@ -0,0 +1,88 @@
+<?php
+
+namespace Doctrine\DBAL;
+
+class DBALException extends \Exception
+{
+    public static function notSupported($method)
+    {
+        return new self("Operation '$method' is not supported by platform.");
+    }
+
+    public static function invalidPlatformSpecified()
+    {
+        return new self(
+            "Invalid 'platform' option specified, need to give an instance of ".
+            "\Doctrine\DBAL\Platforms\AbstractPlatform.");
+    }
+
+    public static function invalidPdoInstance()
+    {
+        return new self(
+            "The 'pdo' option was used in DriverManager::getConnection() but no ".
+            "instance of PDO was given."
+        );
+    }
+
+    public static function driverRequired()
+    {
+        return new self("The options 'driver' or 'driverClass' are mandatory if no PDO ".
+            "instance is given to DriverManager::getConnection().");
+    }
+
+    public static function unknownDriver($unknownDriverName, array $knownDrivers)
+    {
+        return new self("The given 'driver' ".$unknownDriverName." is unknown, ".
+            "Doctrine currently supports only the following drivers: ".implode(", ", $knownDrivers));
+    }
+
+    public static function invalidWrapperClass($wrapperClass)
+    {
+        return new self("The given 'wrapperClass' ".$wrapperClass." has to be a ".
+            "subtype of \Doctrine\DBAL\Connection.");
+    }
+
+    public static function invalidDriverClass($driverClass)
+    {
+        return new self("The given 'driverClass' ".$driverClass." has to implement the ".
+            "\Doctrine\DBAL\Driver interface.");
+    }
+
+    /**
+     * @param string $tableName
+     * @return DBALException
+     */
+    public static function invalidTableName($tableName)
+    {
+        return new self("Invalid table name specified: ".$tableName);
+    }
+
+    /**
+     * @param string $tableName
+     * @return DBALException
+     */
+    public static function noColumnsSpecifiedForTable($tableName)
+    {
+        return new self("No columns specified for table ".$tableName);
+    }
+
+    public static function limitOffsetInvalid()
+    {
+        return new self("Invalid Offset in Limit Query, it has to be larger or equal to 0.");
+    }
+
+    public static function typeExists($name)
+    {
+        return new self('Type '.$name.' already exists.');
+    }
+
+    public static function unknownColumnType($name)
+    {
+        return new self('Unknown column type '.$name.' requested.');
+    }
+
+    public static function typeNotFound($name)
+    {
+        return new self('Type to be overwritten '.$name.' does not exist.');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Driver interface.
+ * Interface that all DBAL drivers must implement.
+ *
+ * @since 2.0
+ */
+interface Driver
+{
+    /**
+     * Attempts to create a connection with the database.
+     *
+     * @param array $params All connection parameters passed by the user.
+     * @param string $username The username to use when connecting.
+     * @param string $password The password to use when connecting.
+     * @param array $driverOptions The driver options to use when connecting.
+     * @return Doctrine\DBAL\Driver\Connection The database connection.
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array());
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform();
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn);
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName();
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(Connection $conn);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Connection.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+/**
+ * Connection interface.
+ * Driver connections must implement this interface.
+ *
+ * This resembles (a subset of) the PDO interface.
+ *
+ * @since 2.0
+ */
+interface Connection
+{
+    function prepare($prepareString);
+    function query();
+    function quote($input, $type=\PDO::PARAM_STR);
+    function exec($statement);
+    function lastInsertId($name = null);
+    function beginTransaction();
+    function commit();
+    function rollBack();
+    function errorCode();
+    function errorInfo();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php	(revision 345)
@@ -0,0 +1,115 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+class DB2Connection implements \Doctrine\DBAL\Driver\Connection
+{
+    private $_conn = null;
+
+    public function __construct(array $params, $username, $password, $driverOptions = array())
+    {
+        $isPersistant = (isset($params['persistent']) && $params['persistent'] == true);
+
+        if ($isPersistant) {
+            $this->_conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
+        } else {
+            $this->_conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
+        }
+        if (!$this->_conn) {
+            throw new DB2Exception(db2_conn_errormsg());
+        }
+    }
+
+    public function prepare($sql)
+    {
+        $stmt = @db2_prepare($this->_conn, $sql);
+        if (!$stmt) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return new DB2Statement($stmt);
+    }
+
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    public function quote($input, $type=\PDO::PARAM_STR)
+    {
+        $input = db2_escape_string($input);
+        if ($type == \PDO::PARAM_INT ) {
+            return $input;
+        } else {
+            return "'".$input."'";
+        }
+    }
+
+    public function exec($statement)
+    {
+        $stmt = $this->prepare($statement);
+        $stmt->execute();
+        return $stmt->rowCount();
+    }
+
+    public function lastInsertId($name = null)
+    {
+        return db2_last_insert_id($this->_conn);
+    }
+
+    public function beginTransaction()
+    {
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_OFF);
+    }
+
+    public function commit()
+    {
+        if (!db2_commit($this->_conn)) {
+            throw new DB2Exception(db2_conn_errormsg($this->_conn));
+        }
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
+    }
+
+    public function rollBack()
+    {
+        if (!db2_rollback($this->_conn)) {
+            throw new DB2Exception(db2_conn_errormsg($this->_conn));
+        }
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
+    }
+
+    public function errorCode()
+    {
+        return db2_conn_error($this->_conn);
+    }
+
+    public function errorInfo()
+    {
+        return array(
+            0 => db2_conn_errormsg($this->_conn),
+            1 => $this->errorCode(),
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php	(revision 345)
@@ -0,0 +1,111 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+use Doctrine\DBAL\Driver,
+    Doctrine\DBAL\Connection;
+
+/**
+ * IBM DB2 Driver
+ *
+ * @since 2.0
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DB2Driver implements Driver
+{
+    /**
+     * Attempts to create a connection with the database.
+     *
+     * @param array $params All connection parameters passed by the user.
+     * @param string $username The username to use when connecting.
+     * @param string $password The password to use when connecting.
+     * @param array $driverOptions The driver options to use when connecting.
+     * @return Doctrine\DBAL\Driver\Connection The database connection.
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        if ( ! isset($params['protocol'])) {
+            $params['protocol'] = 'TCPIP';
+        }
+
+        if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') {
+            // if the host isn't localhost, use extended connection params
+            $params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' .
+                     ';DATABASE=' . $params['dbname'] .
+                     ';HOSTNAME=' . $params['host'] .
+                     ';PROTOCOL=' . $params['protocol'] .
+                     ';UID='      . $username .
+                     ';PWD='      . $password .';';
+            if (isset($params['port'])) {
+                $params['dbname'] .= 'PORT=' . $params['port'];
+            }
+
+            $username = null;
+            $password = null;
+        }
+
+        return new DB2Connection($params, $username, $password, $driverOptions);
+    }
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\DB2Platform;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
+    }
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName()
+    {
+        return 'ibm_db2';
+    }
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php	(revision 345)
@@ -0,0 +1,27 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+class DB2Exception extends \Exception
+{
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php	(revision 345)
@@ -0,0 +1,215 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+use \Doctrine\DBAL\Driver\Statement;
+
+class DB2Statement implements \IteratorAggregate, Statement
+{
+    private $_stmt = null;
+
+    private $_bindParam = array();
+
+    private $_defaultFetchStyle = \PDO::FETCH_BOTH;
+
+    /**
+     * DB2_BINARY, DB2_CHAR, DB2_DOUBLE, or DB2_LONG
+     * @var array
+     */
+    static private $_typeMap = array(
+        \PDO::PARAM_INT => DB2_LONG,
+        \PDO::PARAM_STR => DB2_CHAR,
+    );
+
+    public function __construct($stmt)
+    {
+        $this->_stmt = $stmt;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        return $this->bindParam($param, $value, $type);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        $this->_bindParam[$column] =& $variable;
+
+        if ($type && isset(self::$_typeMap[$type])) {
+            $type = self::$_typeMap[$type];
+        } else {
+            $type = DB2_CHAR;
+        }
+
+        if (!db2_bind_param($this->_stmt, $column, "variable", DB2_PARAM_IN, $type)) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function closeCursor()
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+
+        $this->_bindParam = array();
+        db2_free_result($this->_stmt);
+        $ret = db2_free_stmt($this->_stmt);
+        $this->_stmt = false;
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+        return db2_num_fields($this->_stmt);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return db2_stmt_error();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return array(
+            0 => db2_stmt_errormsg(),
+            1 => db2_stmt_error(),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+
+        /*$retval = true;
+        if ($params !== null) {
+            $retval = @db2_execute($this->_stmt, $params);
+        } else {
+            $retval = @db2_execute($this->_stmt);
+        }*/
+        if ($params === null) {
+            ksort($this->_bindParam);
+            $params = array_values($this->_bindParam);
+        }
+        $retval = @db2_execute($this->_stmt, $params);
+
+        if ($retval === false) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return $retval;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchStyle = \PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchStyle;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        switch ($fetchStyle) {
+            case \PDO::FETCH_BOTH:
+                return db2_fetch_both($this->_stmt);
+            case \PDO::FETCH_ASSOC:
+                return db2_fetch_assoc($this->_stmt);
+            case \PDO::FETCH_NUM:
+                return db2_fetch_array($this->_stmt);
+            default:
+                throw new DB2Exception("Given Fetch-Style " . $fetchStyle . " is not supported.");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(\PDO::FETCH_NUM);
+        if ($row && isset($row[$columnIndex])) {
+            return $row[$columnIndex];
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        return (@db2_num_rows($this->_stmt))?:0;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/Driver.php	(revision 345)
@@ -0,0 +1,69 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver as DriverInterface;
+
+/**
+ * @author Kim HemsÃž Rasmussen <kimhemsoe@gmail.com>
+ */
+class Driver implements DriverInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new MysqliConnection($params, $username, $password, $driverOptions);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'mysqli';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\MySqlPlatform();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php	(revision 345)
@@ -0,0 +1,146 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver\Connection as Connection;
+
+/**
+ * @author Kim HemsÃž Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliConnection implements Connection
+{
+    /**
+     * @var \mysqli
+     */
+    private $_conn;
+
+    public function __construct(array $params, $username, $password, array $driverOptions = array())
+    {
+        $port = isset($params['port']) ? $params['port'] : ini_get('mysqli.default_port');
+        $socket = isset($params['unix_socket']) ? $params['unix_socket'] : ini_get('mysqli.default_socket');
+
+        $this->_conn = mysqli_init();
+        if (!$this->_conn->real_connect($params['host'], $username, $password, $params['dbname'], $port, $socket)) {
+            throw new MysqliException($this->_conn->connect_error, $this->_conn->connect_errno);
+        }
+
+        if (isset($params['charset'])) {
+            $this->_conn->set_charset($params['charset']);
+        }
+    }
+
+    /**
+     * Retrieve mysqli native resource handle.
+     *
+     * Could be used if part of your application is not using DBAL
+     *
+     * @return mysqli
+     */
+    public function getWrappedResourceHandle()
+    {
+        return $this->_conn;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function prepare($prepareString)
+    {
+        return new MysqliStatement($this->_conn, $prepareString);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function quote($input, $type=\PDO::PARAM_STR)
+    {
+        return "'". $this->_conn->escape_string($input) ."'";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function exec($statement)
+    {
+        $this->_conn->query($statement);
+        return $this->_conn->affected_rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function lastInsertId($name = null)
+    {
+        return $this->_conn->insert_id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function beginTransaction()
+    {
+        $this->_conn->query('START TRANSACTION');
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function commit()
+    {
+        return $this->_conn->commit();
+    }
+
+    /**
+     * {@inheritdoc}non-PHPdoc)
+     */
+    public function rollBack()
+    {
+        return $this->_conn->rollback();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return $this->_conn->errno;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return $this->_conn->error;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliException.php	(revision 345)
@@ -0,0 +1,26 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+/**
+ * @author Kim HemsÃž Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliException extends \Exception
+{}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php	(revision 345)
@@ -0,0 +1,335 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver\Statement;
+use PDO;
+
+/**
+ * @author Kim HemsÃž Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliStatement implements \IteratorAggregate, Statement
+{
+    protected static $_paramTypeMap = array(
+        PDO::PARAM_STR => 's',
+        PDO::PARAM_BOOL => 'i',
+        PDO::PARAM_NULL => 's',
+        PDO::PARAM_INT => 'i',
+        PDO::PARAM_LOB => 's' // TODO Support LOB bigger then max package size.
+    );
+
+    protected $_conn;
+    protected $_stmt;
+
+    /**
+     * @var null|false|array
+     */
+    protected $_columnNames;
+
+    /**
+     * @var null|array
+     */
+    protected $_rowBindedValues;
+
+    /**
+     * @var array
+     */
+    protected $_bindedValues;
+
+    /**
+     * Contains ref values for bindValue()
+     *
+     * @var array
+     */
+    protected $_values = array();
+
+    protected $_defaultFetchStyle = PDO::FETCH_BOTH;
+
+    public function __construct(\mysqli $conn, $prepareString)
+    {
+        $this->_conn = $conn;
+        $this->_stmt = $conn->prepare($prepareString);
+        if (false === $this->_stmt) {
+            throw new MysqliException($this->_conn->error, $this->_conn->errno);
+        }
+
+        $paramCount = $this->_stmt->param_count;
+        if (0 < $paramCount) {
+            // Index 0 is types
+            // Need to init the string else php think we are trying to access it as a array.
+            $bindedValues = array(0 => str_repeat('s', $paramCount));
+            $null = null;
+            for ($i = 1; $i < $paramCount; $i++) {
+                $bindedValues[] =& $null;
+            }
+            $this->_bindedValues = $bindedValues;
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        if (null === $type) {
+            $type = 's';
+        } else {
+            if (isset(self::$_paramTypeMap[$type])) {
+                $type = self::$_paramTypeMap[$type];
+            } else {
+                throw new MysqliException("Unkown type: '{$type}'");
+            }
+        }
+
+        $this->_bindedValues[$column] =& $variable;
+        $this->_bindedValues[0][$column - 1] = 's';
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        if (null === $type) {
+            $type = 's';
+        } else {
+            if (isset(self::$_paramTypeMap[$type])) {
+                $type = self::$_paramTypeMap[$type];
+            } else {
+                throw new MysqliException("Unknown type: '{$type}'");
+            }
+        }
+
+        $this->_values[$param] = $value;
+        $this->_bindedValues[$param] =& $this->_values[$param];
+        $this->_bindedValues[0][$param - 1] = 's';
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if (null !== $this->_bindedValues) {
+            if (null !== $params) {
+                if (!$this->_bindValues($params)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            } else {
+                if (!call_user_func_array(array($this->_stmt, 'bind_param'), $this->_bindedValues)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            }
+        }
+
+        if (!$this->_stmt->execute()) {
+            throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+        }
+
+        if (null === $this->_columnNames) {
+            $meta = $this->_stmt->result_metadata();
+            if (false !== $meta) {
+                $columnNames = array();
+                foreach ($meta->fetch_fields() as $col) {
+                    $columnNames[] = $col->name;
+                }
+                $meta->free();
+
+                $this->_columnNames = $columnNames;
+                $this->_rowBindedValues = array_fill(0, count($columnNames), NULL);
+
+                $refs = array();
+                foreach ($this->_rowBindedValues as $key => &$value) {
+                    $refs[$key] =& $value;
+                }
+
+                if (!call_user_func_array(array($this->_stmt, 'bind_result'), $refs)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            } else {
+                $this->_columnNames = false;
+            }
+        }
+
+        // We have a result.
+        if (false !== $this->_columnNames) {
+            $this->_stmt->store_result();
+        }
+        return true;
+    }
+
+    /**
+     * Bind a array of values to bound parameters
+     *
+     * @param array $values
+     * @return boolean
+     */
+    private function _bindValues($values)
+    {
+        $params = array();
+        $types = str_repeat('s', count($values));
+        $params[0] = $types;
+
+        foreach ($values as &$v) {
+            $params[] =& $v;
+        }
+        return call_user_func_array(array($this->_stmt, 'bind_param'), $params);
+    }
+
+    /**
+     * @return null|false|array
+     */
+    private function _fetch()
+    {
+        $ret = $this->_stmt->fetch();
+
+        if (true === $ret) {
+            $values = array();
+            foreach ($this->_rowBindedValues as $v) {
+                // Mysqli converts them to a scalar type it can fit in.
+                $values[] = null === $v ? null : (string)$v;
+            }
+            return $values;
+        }
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $values = $this->_fetch();
+        if (null === $values) {
+            return null;
+        }
+
+        if (false === $values) {
+            throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+        }
+
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+
+        switch ($fetchStyle) {
+            case PDO::FETCH_NUM:
+                return $values;
+
+            case PDO::FETCH_ASSOC:
+                return array_combine($this->_columnNames, $values);
+
+            case PDO::FETCH_BOTH:
+                $ret = array_combine($this->_columnNames, $values);
+                $ret += $values;
+                return $ret;
+
+            default:
+                throw new MysqliException("Unknown fetch type '{$fetchStyle}'");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+
+        $a = array();
+        while (($row = $this->fetch($fetchStyle)) !== null) {
+            $a[] = $row;
+        }
+        return $a;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (null === $row) {
+            return null;
+        }
+        return $row[$columnIndex];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return $this->_stmt->errno;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return $this->_stmt->error;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function closeCursor()
+    {
+        $this->_stmt->free_result();
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        if (false === $this->_columnNames) {
+            return $this->_stmt->affected_rows;
+        }
+        return $this->_stmt->num_rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        return $this->_stmt->field_count;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchMode = PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchMode;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/Driver.php	(revision 345)
@@ -0,0 +1,95 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new OCI8Connection(
+            $username,
+            $password,
+            $this->_constructDsn($params),
+            isset($params['charset']) ? $params['charset'] : null,
+            isset($params['sessionMode']) ? $params['sessionMode'] : OCI_DEFAULT
+        );
+    }
+
+    /**
+     * Constructs the Oracle DSN.
+     *
+     * @return string The DSN.
+     */
+    protected function _constructDsn(array $params)
+    {
+        $dsn = '';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
+                   '(HOST=' . $params['host'] . ')';
+
+            if (isset($params['port'])) {
+                $dsn .= '(PORT=' . $params['port'] . ')';
+            } else {
+                $dsn .= '(PORT=1521)';
+            }
+
+            if (isset($params['service']) && $params['service'] == true) {
+                $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))';
+            } else {
+                $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
+            }
+        } else {
+            $dsn .= $params['dbname'];
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\OraclePlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'oci8';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['user'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php	(revision 345)
@@ -0,0 +1,164 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+/**
+ * OCI8 implementation of the Connection interface.
+ *
+ * @since 2.0
+ */
+class OCI8Connection implements \Doctrine\DBAL\Driver\Connection
+{
+    protected $_dbh;
+
+    protected $_executeMode = OCI_COMMIT_ON_SUCCESS;
+
+    /**
+     * Create a Connection to an Oracle Database using oci8 extension.
+     *
+     * @param string $username
+     * @param string $password
+     * @param string $db
+     */
+    public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT)
+    {
+        if (!defined('OCI_NO_AUTO_COMMIT')) {
+            define('OCI_NO_AUTO_COMMIT', 0);
+        }
+
+        $this->_dbh = @oci_connect($username, $password, $db, $charset, $sessionMode);
+        if (!$this->_dbh) {
+            throw OCI8Exception::fromErrorInfo(oci_error());
+        }
+    }
+
+    /**
+     * Create a non-executed prepared statement.
+     *
+     * @param  string $prepareString
+     * @return OCI8Statement
+     */
+    public function prepare($prepareString)
+    {
+        return new OCI8Statement($this->_dbh, $prepareString, $this->_executeMode);
+    }
+
+    /**
+     * @param string $sql
+     * @return OCI8Statement
+     */
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        //$fetchMode = $args[1];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    /**
+     * Quote input value.
+     *
+     * @param mixed $input
+     * @param int $type PDO::PARAM*
+     * @return mixed
+     */
+    public function quote($value, $type=\PDO::PARAM_STR)
+    {
+        if (is_int($value) || is_float($value)) {
+            return $value;
+        }
+        $value = str_replace("'", "''", $value);
+        return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
+    }
+
+    /**
+     *
+     * @param  string $statement
+     * @return int
+     */
+    public function exec($statement)
+    {
+        $stmt = $this->prepare($statement);
+        $stmt->execute();
+        return $stmt->rowCount();
+    }
+
+    public function lastInsertId($name = null)
+    {
+        //TODO: throw exception or support sequences?
+    }
+
+    /**
+     * Start a transactiom
+     *
+     * Oracle has to explicitly set the autocommit mode off. That means
+     * after connection, a commit or rollback there is always automatically
+     * opened a new transaction.
+     *
+     * @return bool
+     */
+    public function beginTransaction()
+    {
+        $this->_executeMode = OCI_NO_AUTO_COMMIT;
+        return true;
+    }
+
+    /**
+     * @throws OCI8Exception
+     * @return bool
+     */
+    public function commit()
+    {
+        if (!oci_commit($this->_dbh)) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        $this->_executeMode = OCI_COMMIT_ON_SUCCESS;
+        return true;
+    }
+
+    /**
+     * @throws OCI8Exception
+     * @return bool
+     */
+    public function rollBack()
+    {
+        if (!oci_rollback($this->_dbh)) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        $this->_executeMode = OCI_COMMIT_ON_SUCCESS;
+        return true;
+    }
+
+    public function errorCode()
+    {
+        $error = oci_error($this->_dbh);
+        if ($error !== false) {
+            $error = $error['code'];
+        }
+        return $error;
+    }
+
+    public function errorInfo()
+    {
+        return oci_error($this->_dbh);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+class OCI8Exception extends \Exception
+{
+    static public function fromErrorInfo($error)
+    {
+        return new self($error['message'], $error['code']);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php	(revision 345)
@@ -0,0 +1,258 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+use PDO;
+use IteratorAggregate;
+use Doctrine\DBAL\Driver\Statement;
+
+/**
+ * The OCI8 implementation of the Statement interface.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class OCI8Statement implements \IteratorAggregate, Statement
+{
+    /** Statement handle. */
+    protected $_dbh;
+    protected $_sth;
+    protected $_executeMode;
+    protected static $_PARAM = ':param';
+    protected static $fetchStyleMap = array(
+        PDO::FETCH_BOTH => OCI_BOTH,
+        PDO::FETCH_ASSOC => OCI_ASSOC,
+        PDO::FETCH_NUM => OCI_NUM,
+        PDO::PARAM_LOB => OCI_B_BLOB,
+    );
+    protected $_defaultFetchStyle = PDO::FETCH_BOTH;
+    protected $_paramMap = array();
+
+    /**
+     * Creates a new OCI8Statement that uses the given connection handle and SQL statement.
+     *
+     * @param resource $dbh The connection handle.
+     * @param string $statement The SQL statement.
+     */
+    public function __construct($dbh, $statement, $executeMode)
+    {
+        list($statement, $paramMap) = self::convertPositionalToNamedPlaceholders($statement);
+        $this->_sth = oci_parse($dbh, $statement);
+        $this->_dbh = $dbh;
+        $this->_paramMap = $paramMap;
+        $this->_executeMode = $executeMode;
+    }
+
+    /**
+     * Convert positional (?) into named placeholders (:param<num>)
+     *
+     * Oracle does not support positional parameters, hence this method converts all
+     * positional parameters into artificially named parameters. Note that this conversion
+     * is not perfect. All question marks (?) in the original statement are treated as
+     * placeholders and converted to a named parameter.
+     *
+     * The algorithm uses a state machine with two possible states: InLiteral and NotInLiteral.
+     * Question marks inside literal strings are therefore handled correctly by this method.
+     * This comes at a cost, the whole sql statement has to be looped over.
+     *
+     * @todo extract into utility class in Doctrine\DBAL\Util namespace
+     * @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements.
+     * @param string $statement The SQL statement to convert.
+     * @return string
+     */
+    static public function convertPositionalToNamedPlaceholders($statement)
+    {
+        $count = 1;
+        $inLiteral = false; // a valid query never starts with quotes
+        $stmtLen = strlen($statement);
+        $paramMap = array();
+        for ($i = 0; $i < $stmtLen; $i++) {
+            if ($statement[$i] == '?' && !$inLiteral) {
+                // real positional parameter detected
+                $paramMap[$count] = ":param$count";
+                $len = strlen($paramMap[$count]);
+                $statement = substr_replace($statement, ":param$count", $i, 1);
+                $i += $len-1; // jump ahead
+                $stmtLen = strlen($statement); // adjust statement length
+                ++$count;
+            } else if ($statement[$i] == "'" || $statement[$i] == '"') {
+                $inLiteral = ! $inLiteral; // switch state!
+            }
+        }
+
+        return array($statement, $paramMap);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        return $this->bindParam($param, $value, $type);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        $column = isset($this->_paramMap[$column]) ? $this->_paramMap[$column] : $column;
+
+        if ($type == \PDO::PARAM_LOB) {
+            $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
+            $lob->writeTemporary($variable, OCI_TEMP_BLOB);
+
+            return oci_bind_by_name($this->_sth, $column, $lob, -1, OCI_B_BLOB);
+        } else {
+            return oci_bind_by_name($this->_sth, $column, $variable);
+        }
+    }
+
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function closeCursor()
+    {
+        return oci_free_statement($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        return oci_num_fields($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        $error = oci_error($this->_sth);
+        if ($error !== false) {
+            $error = $error['code'];
+        }
+        return $error;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return oci_error($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if ($params) {
+            $hasZeroIndex = array_key_exists(0, $params);
+            foreach ($params as $key => $val) {
+                if ($hasZeroIndex && is_numeric($key)) {
+                    $this->bindValue($key + 1, $val);
+                } else {
+                    $this->bindValue($key, $val);
+                }
+            }
+        }
+
+        $ret = @oci_execute($this->_sth, $this->_executeMode);
+        if ( ! $ret) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchStyle;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
+            throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
+        }
+
+        return oci_fetch_array($this->_sth, self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
+            throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
+        }
+
+        $result = array();
+        if (self::$fetchStyleMap[$fetchStyle] === OCI_BOTH) {
+            while ($row = $this->fetch($fetchStyle)) {
+                $result[] = $row;
+            }
+        } else {
+            oci_fetch_all($this->_sth, $result, 0, -1,
+                self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_FETCHSTATEMENT_BY_ROW | OCI_RETURN_LOBS);
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = oci_fetch_array($this->_sth, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
+        return $row[$columnIndex];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        return oci_num_rows($this->_sth);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOConnection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOConnection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOConnection.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+use \PDO;
+
+/**
+ * PDO implementation of the Connection interface.
+ * Used by all PDO-based drivers.
+ *
+ * @since 2.0
+ */
+class PDOConnection extends PDO implements Connection
+{
+    public function __construct($dsn, $user = null, $password = null, array $options = null)
+    {
+        parent::__construct($dsn, $user, $password, $options);
+        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine\DBAL\Driver\PDOStatement', array()));
+        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOIbm/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOIbm/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOIbm/Driver.php	(revision 345)
@@ -0,0 +1,126 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\PDOIbm;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * Driver for the PDO IBM extension
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to establish a connection with the underlying driver.
+     *
+     * @param array $params
+     * @param string $username
+     * @param string $password
+     * @param array $driverOptions
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        $conn = new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+        return $conn;
+    }
+
+    /**
+     * Constructs the MySql PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'ibm:';
+        if (isset($params['host'])) {
+            $dsn .= 'HOSTNAME=' . $params['host'] . ';';
+        }
+        if (isset($params['port'])) {
+            $dsn .= 'PORT=' . $params['port'] . ';';
+        }
+        $dsn .= 'PROTOCOL=TCPIP;';
+        if (isset($params['dbname'])) {
+            $dsn .= 'DATABASE=' . $params['dbname'] . ';';
+        }
+
+        return $dsn;
+    }
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\DB2Platform;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
+    }
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName()
+    {
+        return 'pdo_ibm';
+    }
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOMySql/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOMySql/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOMySql/Driver.php	(revision 345)
@@ -0,0 +1,102 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOMySql;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * PDO MySql driver.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to establish a connection with the underlying driver.
+     *
+     * @param array $params
+     * @param string $username
+     * @param string $password
+     * @param array $driverOptions
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        $conn = new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+        return $conn;
+    }
+
+    /**
+     * Constructs the MySql PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'mysql:';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= 'host=' . $params['host'] . ';';
+        }
+        if (isset($params['port'])) {
+            $dsn .= 'port=' . $params['port'] . ';';
+        }
+        if (isset($params['dbname'])) {
+            $dsn .= 'dbname=' . $params['dbname'] . ';';
+        }
+        if (isset($params['unix_socket'])) {
+            $dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
+        }
+        if (isset($params['charset'])) {
+            $dsn .= 'charset=' . $params['charset'] . ';';
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\MySqlPlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_mysql';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+
+        if (isset($params['dbname'])) {
+            return $params['dbname'];
+        }
+        return $conn->query('SELECT DATABASE()')->fetchColumn();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOOracle/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOOracle/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOOracle/Driver.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOOracle;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * PDO Oracle driver
+ *
+ * WARNING: This driver gives us segfauls in our testsuites on CLOB and other
+ * stuff. PDO Oracle is not maintained by Oracle or anyone in the PHP community,
+ * which leads us to the recommendation to use the "oci8" driver to connect
+ * to Oracle instead.
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+    }
+
+    /**
+     * Constructs the Oracle PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'oci:';
+        if (isset($params['host'])) {
+            $dsn .= 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
+                   '(HOST=' . $params['host'] . ')';
+
+            if (isset($params['port'])) {
+                $dsn .= '(PORT=' . $params['port'] . ')';
+            } else {
+                $dsn .= '(PORT=1521)';
+            }
+
+            if (isset($params['service']) && $params['service'] == true) {
+                $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))';
+            } else {
+                $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
+            }
+        } else {
+            $dsn .= 'dbname=' . $params['dbname'];
+        }
+
+        if (isset($params['charset'])) {
+            $dsn .= ';charset=' . $params['charset'];
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\OraclePlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_oracle';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['user'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOPgSql/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOPgSql/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOPgSql/Driver.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\PDOPgSql;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * Driver that connects through pdo_pgsql.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to connect to the database and returns a driver connection on success.
+     *
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+    }
+
+    /**
+     * Constructs the Postgres PDO DSN.
+     *
+     * @return string The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'pgsql:';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= 'host=' . $params['host'] . ' ';
+        }
+        if (isset($params['port']) && $params['port'] != '') {
+            $dsn .= 'port=' . $params['port'] . ' ';
+        }
+        if (isset($params['dbname'])) {
+            $dsn .= 'dbname=' . $params['dbname'] . ' ';
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\PostgreSqlPlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\PostgreSqlSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_pgsql';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlite/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlite/Driver.php	(revision 345)
@@ -0,0 +1,116 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOSqlite;
+
+/**
+ * The PDO Sqlite driver.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * @var array
+     */
+    protected $_userDefinedFunctions = array(
+        'sqrt' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfSqrt'), 'numArgs' => 1),
+        'mod'  => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfMod'), 'numArgs' => 2),
+        'locate'  => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfLocate'), 'numArgs' => -1),
+    );
+
+    /**
+     * Tries to establish a database connection to SQLite.
+     *
+     * @param array $params
+     * @param string $username
+     * @param string $password
+     * @param array $driverOptions
+     * @return Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        if (isset($driverOptions['userDefinedFunctions'])) {
+            $this->_userDefinedFunctions = array_merge(
+                $this->_userDefinedFunctions, $driverOptions['userDefinedFunctions']);
+            unset($driverOptions['userDefinedFunctions']);
+        }
+
+        $pdo = new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+
+        foreach ($this->_userDefinedFunctions AS $fn => $data) {
+            $pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']);
+        }
+
+        return $pdo;
+    }
+
+    /**
+     * Constructs the Sqlite PDO DSN.
+     *
+     * @return string  The DSN.
+     * @override
+     */
+    protected function _constructPdoDsn(array $params)
+    {
+        $dsn = 'sqlite:';
+        if (isset($params['path'])) {
+            $dsn .= $params['path'];
+        } else if (isset($params['memory'])) {
+            $dsn .= ':memory:';
+        }
+
+        return $dsn;
+    }
+
+    /**
+     * Gets the database platform that is relevant for this driver.
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\SqlitePlatform();
+    }
+
+    /**
+     * Gets the schema manager that is relevant for this driver.
+     *
+     * @param Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\Schema\SqliteSchemaManager
+     */
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\SqliteSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_sqlite';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return isset($params['path']) ? $params['path'] : null;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOSqlsrv;
+
+/**
+ * Sqlsrv Connection implementation.
+ *
+ * @since 2.0
+ */
+class Connection extends \Doctrine\DBAL\Driver\PDOConnection implements \Doctrine\DBAL\Driver\Connection
+{
+    /**
+     * @override
+     */
+    public function quote($value, $type=\PDO::PARAM_STR)
+    {
+        $val = parent::quote($value, $type);
+
+		// Fix for a driver version terminating all values with null byte
+		if (strpos($val, "\0") !== false) {
+			$val = substr($val, 0, -1);
+		}
+
+		return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php	(revision 345)
@@ -0,0 +1,88 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOSqlsrv;
+
+/**
+ * The PDO-based Sqlsrv driver.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new Connection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+    }
+
+    /**
+     * Constructs the Sqlsrv PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'sqlsrv:server=';
+
+        if (isset($params['host'])) {
+            $dsn .= $params['host'];
+        }
+
+        if (isset($params['port']) && !empty($params['port'])) {
+            $dsn .= ',' . $params['port'];
+        }
+
+        if (isset($params['dbname'])) {;
+            $dsn .= ';Database=' .  $params['dbname'];
+        }
+
+        if (isset($params['MultipleActiveResultSets'])) {
+            $dsn .= '; MultipleActiveResultSets=' . ($params['MultipleActiveResultSets'] ? 'true' : 'false');
+        }
+
+        return $dsn;
+    }
+
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\SQLServer2008Platform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\SQLServerSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_sqlsrv';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/PDOStatement.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ *  $Id: Interface.php 3882 2008-02-22 18:11:35Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+/**
+ * The PDO implementation of the Statement interface.
+ * Used by all PDO-based drivers.
+ *
+ * @since 2.0
+ */
+class PDOStatement extends \PDOStatement implements Statement
+{
+    private function __construct() {}
+
+    public function setFetchMode($fetchStyle, $params = NULL)
+    {
+        // This thin wrapper is necessary to shield against the weird signature
+        // of PDOStatement::setFetchMode(): even if the second and third
+        // parameters are optional, PHP will not let us remove it from this
+        // declaration.
+        return parent::setFetchMode($fetchStyle);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/ResultStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/ResultStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/ResultStatement.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+use PDO;
+
+/**
+ * Interface for the reading part of a prepare statement only.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface ResultStatement extends \Traversable
+{
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    function closeCursor();
+
+
+    /**
+     * columnCount
+     * Returns the number of columns in the result set
+     *
+     * @return integer              Returns the number of columns in the result set represented
+     *                              by the PDOStatement object. If there is no result set,
+     *                              this method should return 0.
+     */
+    function columnCount();
+
+    /**
+     * setFetchMode
+     * Set the fetch mode to use while iterating this statement.
+     *
+     * @param integer $fetchStyle
+     */
+    public function setFetchMode($fetchStyle);
+
+    /**
+     * fetch
+     *
+     * @see Query::HYDRATE_* constants
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $cursorOrientation    For a PDOStatement object representing a scrollable cursor,
+     *                                      this value determines which row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
+     *                                      Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
+     *                                      PDOStatement object,
+     *                                      you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
+     *                                      prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
+     *
+     * @param integer $cursorOffset         For a PDOStatement object representing a scrollable cursor for which the
+     *                                      $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
+     *                                      the absolute number of the row in the result set that shall be fetched.
+     *
+     *                                      For a PDOStatement object representing a scrollable cursor for
+     *                                      which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
+     *                                      specifies the row to fetch relative to the cursor position before
+     *                                      PDOStatement->fetch() was called.
+     *
+     * @return mixed
+     */
+    function fetch($fetchStyle = PDO::FETCH_BOTH);
+
+    /**
+     * Returns an array containing all of the result set rows
+     *
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $columnIndex          Returns the indicated 0-indexed column when the value of $fetchStyle is
+     *                                      Query::HYDRATE_COLUMN. Defaults to 0.
+     *
+     * @return array
+     */
+    function fetchAll($fetchStyle = PDO::FETCH_BOTH);
+
+    /**
+     * fetchColumn
+     * Returns a single column from the next row of a
+     * result set or FALSE if there are no more rows.
+     *
+     * @param integer $columnIndex          0-indexed number of the column you wish to retrieve from the row. If no
+     *                                      value is supplied, PDOStatement->fetchColumn()
+     *                                      fetches the first column.
+     *
+     * @return string                       returns a single column in the next row of a result set.
+     */
+    function fetchColumn($columnIndex = 0);
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Statement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Statement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Driver/Statement.php	(revision 345)
@@ -0,0 +1,124 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+use \PDO;
+
+/**
+ * Statement interface.
+ * Drivers must implement this interface.
+ *
+ * This resembles (a subset of) the PDOStatement interface.
+ *
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ */
+interface Statement extends ResultStatement
+{
+    /**
+     * Binds a value to a corresponding named or positional
+     * placeholder in the SQL statement that was used to prepare the statement.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $value          The value to bind to the parameter.
+     * @param integer $type         Explicit data type for the parameter using the PDO::PARAM_* constants.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    function bindValue($param, $value, $type = null);
+
+    /**
+     * Binds a PHP variable to a corresponding named or question mark placeholder in the
+     * SQL statement that was use to prepare the statement. Unlike PDOStatement->bindValue(),
+     * the variable is bound as a reference and will only be evaluated at the time
+     * that PDOStatement->execute() is called.
+     *
+     * Most parameters are input parameters, that is, parameters that are
+     * used in a read-only fashion to build up the query. Some drivers support the invocation
+     * of stored procedures that return data as output parameters, and some also as input/output
+     * parameters that both send in data and are updated to receive it.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $variable       Name of the PHP variable to bind to the SQL statement parameter.
+     *
+     * @param integer $type         Explicit data type for the parameter using the PDO::PARAM_* constants. To return
+     *                              an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
+     *                              PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    function bindParam($column, &$variable, $type = null);
+
+    /**
+     * errorCode
+     * Fetch the SQLSTATE associated with the last operation on the statement handle
+     *
+     * @see Doctrine_Adapter_Interface::errorCode()
+     * @return string       error code string
+     */
+    function errorCode();
+
+    /**
+     * errorInfo
+     * Fetch extended error information associated with the last operation on the statement handle
+     *
+     * @see Doctrine_Adapter_Interface::errorInfo()
+     * @return array        error info array
+     */
+    function errorInfo();
+
+    /**
+     * Executes a prepared statement
+     *
+     * If the prepared statement included parameter markers, you must either:
+     * call PDOStatement->bindParam() to bind PHP variables to the parameter markers:
+     * bound variables pass their value as input and receive the output value,
+     * if any, of their associated parameter markers or pass an array of input-only
+     * parameter values
+     *
+     *
+     * @param array $params             An array of values with as many elements as there are
+     *                                  bound parameters in the SQL statement being executed.
+     * @return boolean                  Returns TRUE on success or FALSE on failure.
+     */
+    function execute($params = null);
+
+    /**
+     * rowCount
+     * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
+     * executed by the corresponding object.
+     *
+     * If the last SQL statement executed by the associated Statement object was a SELECT statement,
+     * some databases may return the number of rows returned by that statement. However,
+     * this behaviour is not guaranteed for all databases and should not be
+     * relied on for portable applications.
+     *
+     * @return integer                      Returns the number of rows.
+     */
+    function rowCount();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DriverManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DriverManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/DriverManager.php	(revision 345)
@@ -0,0 +1,165 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use Doctrine\Common\EventManager;
+
+/**
+ * Factory for creating Doctrine\DBAL\Connection instances.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+final class DriverManager
+{
+    /**
+     * List of supported drivers and their mappings to the driver classes.
+     *
+     * @var array
+     * @todo REMOVE. Users should directly supply class names instead.
+     */
+     private static $_driverMap = array(
+            'pdo_mysql'  => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
+            'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver',
+            'pdo_pgsql'  => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
+            'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver',
+            'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver',
+            'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver',
+            'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver',
+            'pdo_sqlsrv' => 'Doctrine\DBAL\Driver\PDOSqlsrv\Driver',
+            'mysqli' => 'Doctrine\DBAL\Driver\Mysqli\Driver',
+            );
+
+    /** Private constructor. This class cannot be instantiated. */
+    private function __construct() { }
+
+    /**
+     * Creates a connection object based on the specified parameters.
+     * This method returns a Doctrine\DBAL\Connection which wraps the underlying
+     * driver connection.
+     *
+     * $params must contain at least one of the following.
+     *
+     * Either 'driver' with one of the following values:
+     *     pdo_mysql
+     *     pdo_sqlite
+     *     pdo_pgsql
+     *     pdo_oracle
+     *     pdo_sqlsrv
+     *
+     * OR 'driverClass' that contains the full class name (with namespace) of the
+     * driver class to instantiate.
+     *
+     * Other (optional) parameters:
+     *
+     * <b>user (string)</b>:
+     * The username to use when connecting.
+     *
+     * <b>password (string)</b>:
+     * The password to use when connecting.
+     *
+     * <b>driverOptions (array)</b>:
+     * Any additional driver-specific options for the driver. These are just passed
+     * through to the driver.
+     *
+     * <b>pdo</b>:
+     * You can pass an existing PDO instance through this parameter. The PDO
+     * instance will be wrapped in a Doctrine\DBAL\Connection.
+     *
+     * <b>wrapperClass</b>:
+     * You may specify a custom wrapper class through the 'wrapperClass'
+     * parameter but this class MUST inherit from Doctrine\DBAL\Connection.
+     *
+     * <b>driverClass</b>:
+     * The driver class to use.
+     *
+     * @param array $params The parameters.
+     * @param Doctrine\DBAL\Configuration The configuration to use.
+     * @param Doctrine\Common\EventManager The event manager to use.
+     * @return Doctrine\DBAL\Connection
+     */
+    public static function getConnection(
+            array $params,
+            Configuration $config = null,
+            EventManager $eventManager = null)
+    {
+        // create default config and event manager, if not set
+        if ( ! $config) {
+            $config = new Configuration();
+        }
+        if ( ! $eventManager) {
+            $eventManager = new EventManager();
+        }
+
+        // check for existing pdo object
+        if (isset($params['pdo']) && ! $params['pdo'] instanceof \PDO) {
+            throw DBALException::invalidPdoInstance();
+        } else if (isset($params['pdo'])) {
+            $params['pdo']->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+            $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME);
+        } else {
+            self::_checkParams($params);
+        }
+        if (isset($params['driverClass'])) {
+            $className = $params['driverClass'];
+        } else {
+            $className = self::$_driverMap[$params['driver']];
+        }
+
+        $driver = new $className();
+
+        $wrapperClass = 'Doctrine\DBAL\Connection';
+        if (isset($params['wrapperClass'])) {
+            if (is_subclass_of($params['wrapperClass'], $wrapperClass)) {
+               $wrapperClass = $params['wrapperClass'];
+            } else {
+                throw DBALException::invalidWrapperClass($params['wrapperClass']);
+            }
+        }
+
+        return new $wrapperClass($params, $driver, $config, $eventManager);
+    }
+
+    /**
+     * Checks the list of parameters.
+     *
+     * @param array $params
+     */
+    private static function _checkParams(array $params)
+    {
+        // check existance of mandatory parameters
+
+        // driver
+        if ( ! isset($params['driver']) && ! isset($params['driverClass'])) {
+            throw DBALException::driverRequired();
+        }
+
+        // check validity of parameters
+
+        // driver
+        if ( isset($params['driver']) && ! isset(self::$_driverMap[$params['driver']])) {
+            throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap));
+        }
+
+        if (isset($params['driverClass']) && ! in_array('Doctrine\DBAL\Driver', class_implements($params['driverClass'], true))) {
+            throw DBALException::invalidDriverClass($params['driverClass']);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/ConnectionEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/ConnectionEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/ConnectionEventArgs.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\Common\EventArgs,
+    Doctrine\DBAL\Connection;
+
+/**
+ * Event Arguments used when a Driver connection is established inside Doctrine\DBAL\Connection.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ConnectionEventArgs extends EventArgs
+{
+    /**
+     * @var Connection
+     */
+    private $_connection = null;
+
+    public function __construct(Connection $connection)
+    {
+        $this->_connection = $connection;
+    }
+
+    /**
+     * @return Doctrine\DBAL\Connection
+     */
+    public function getConnection()
+    {
+        return $this->_connection;
+    }
+
+    /**
+     * @return Doctrine\DBAL\Driver
+     */
+    public function getDriver()
+    {
+        return $this->_connection->getDriver();
+    }
+
+    /**
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_connection->getDatabasePlatform();
+    }
+
+    /**
+     * @return Doctrine\DBAL\Schema\AbstractSchemaManager
+     */
+    public function getSchemaManager()
+    {
+        return $this->_connection->getSchemaManager();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php	(revision 345)
@@ -0,0 +1,74 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event\Listeners;
+
+use Doctrine\DBAL\Event\ConnectionEventArgs;
+use Doctrine\DBAL\Events;
+use Doctrine\Common\EventSubscriber;
+
+/**
+ * MySQL Session Init Event Subscriber which allows to set the Client Encoding of the Connection
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @deprecated  Use "charset" option to PDO MySQL Connection instead.
+ */
+class MysqlSessionInit implements EventSubscriber
+{
+    /**
+     * @var string
+     */
+    private $_charset;
+
+    /**
+     * @var string
+     */
+    private $_collation;
+
+    /**
+     * Configure Charset and Collation options of MySQL Client for each Connection
+     *
+     * @param string $charset
+     * @param string $collation
+     */
+    public function __construct($charset = 'utf8', $collation = false)
+    {
+        $this->_charset = $charset;
+        $this->_collation = $collation;
+    }
+
+    /**
+     * @param ConnectionEventArgs $args
+     * @return void
+     */
+    public function postConnect(ConnectionEventArgs $args)
+    {
+        $collation = ($this->_collation) ? " COLLATE ".$this->_collation : "";
+        $args->getConnection()->executeUpdate("SET NAMES ".$this->_charset . $collation);
+    }
+
+    public function getSubscribedEvents()
+    {
+        return array(Events::postConnect);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event\Listeners;
+
+use Doctrine\DBAL\Event\ConnectionEventArgs;
+use Doctrine\DBAL\Events;
+use Doctrine\Common\EventSubscriber;
+
+/**
+ * Should be used when Oracle Server default enviroment does not match the Doctrine requirements.
+ *
+ * The following enviroment variables are required for the Doctrine default date format:
+ *
+ * NLS_TIME_FORMAT="HH24:MI:SS"
+ * NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"
+ * NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS"
+ * NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS TZH:TZM"
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OracleSessionInit implements EventSubscriber
+{
+    protected $_defaultSessionVars = array(
+        'NLS_TIME_FORMAT' => "HH24:MI:SS",
+        'NLS_DATE_FORMAT' => "YYYY-MM-DD HH24:MI:SS",
+        'NLS_TIMESTAMP_FORMAT' => "YYYY-MM-DD HH24:MI:SS",
+        'NLS_TIMESTAMP_TZ_FORMAT' => "YYYY-MM-DD HH24:MI:SS TZH:TZM",
+    );
+
+    /**
+     * @param array $oracleSessionVars
+     */
+    public function __construct(array $oracleSessionVars = array())
+    {
+        $this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars);
+    }
+
+    /**
+     * @param ConnectionEventArgs $args
+     * @return void
+     */
+    public function postConnect(ConnectionEventArgs $args)
+    {
+        if (count($this->_defaultSessionVars)) {
+            array_change_key_case($this->_defaultSessionVars, \CASE_UPPER);
+            $vars = array();
+            foreach ($this->_defaultSessionVars AS $option => $value) {
+                $vars[] = $option." = '".$value."'";
+            }
+            $sql = "ALTER SESSION SET ".implode(" ", $vars);
+            $args->getConnection()->executeUpdate($sql);
+        }
+    }
+
+    public function getSubscribedEvents()
+    {
+        return array(Events::postConnect);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php	(revision 345)
@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event\Listeners;
+
+use Doctrine\DBAL\Event\ConnectionEventArgs;
+use Doctrine\DBAL\Events;
+use Doctrine\Common\EventSubscriber;
+
+/**
+ * Session init listener for executing a single SQL statement right after a connection is opened.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SQLSessionInit implements EventSubscriber
+{
+    /**
+     * @var string
+     */
+    protected $sql;
+
+    /**
+     * @param string $sql
+     */
+    public function __construct($sql)
+    {
+        $this->sql = $sql;
+    }
+
+    /**
+     * @param ConnectionEventArgs $args
+     * @return void
+     */
+    public function postConnect(ConnectionEventArgs $args)
+    {
+        $conn = $args->getConnection();
+        $conn->exec($this->sql);
+    }
+
+    public function getSubscribedEvents()
+    {
+        return array(Events::postConnect);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php	(revision 345)
@@ -0,0 +1,114 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * Event Arguments used when SQL queries for adding table columns are generated inside Doctrine\DBAL\Platform\*Platform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaAlterTableAddColumnEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Column
+     */
+    private $_column = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\TableDiff
+     */
+    private $_tableDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\Column $column
+     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(Column $column, TableDiff $tableDiff, AbstractPlatform $platform)
+    {
+        $this->_column    = $column;
+        $this->_tableDiff = $tableDiff;
+        $this->_platform  = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getColumn()
+    {
+        return $this->_column;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getTableDiff()
+    {
+        return $this->_tableDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php	(revision 345)
@@ -0,0 +1,114 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\ColumnDiff,
+    Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * Event Arguments used when SQL queries for changing table columns are generated inside Doctrine\DBAL\Platform\*Platform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaAlterTableChangeColumnEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\ColumnDiff
+     */
+    private $_columnDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\TableDiff
+     */
+    private $_tableDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\ColumnDiff $columnDiff
+     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(ColumnDiff $columnDiff, TableDiff $tableDiff, AbstractPlatform $platform)
+    {
+        $this->_columnDiff = $columnDiff;
+        $this->_tableDiff  = $tableDiff;
+        $this->_platform   = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\ColumnDiff
+     */
+    public function getColumnDiff()
+    {
+        return $this->_columnDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getTableDiff()
+    {
+        return $this->_tableDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php	(revision 345)
@@ -0,0 +1,99 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * Event Arguments used when SQL queries for creating tables are generated inside Doctrine\DBAL\Platform\*Platform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaAlterTableEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\TableDiff
+     */
+    private $_tableDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(TableDiff $tableDiff, AbstractPlatform $platform)
+    {
+        $this->_tableDiff = $tableDiff;
+        $this->_platform  = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getTableDiff()
+    {
+        return $this->_tableDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaAlterTableEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php	(revision 345)
@@ -0,0 +1,114 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * Event Arguments used when SQL queries for removing table columns are generated inside Doctrine\DBAL\Platform\*Platform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaAlterTableRemoveColumnEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Column
+     */
+    private $_column = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\TableDiff
+     */
+    private $_tableDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\Column $column
+     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(Column $column, TableDiff $tableDiff, AbstractPlatform $platform)
+    {
+        $this->_column    = $column;
+        $this->_tableDiff = $tableDiff;
+        $this->_platform  = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getColumn()
+    {
+        return $this->_column;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getTableDiff()
+    {
+        return $this->_tableDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php	(revision 345)
@@ -0,0 +1,129 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * Event Arguments used when SQL queries for renaming table columns are generated inside Doctrine\DBAL\Platform\*Platform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaAlterTableRenameColumnEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var string
+     */
+    private $_oldColumnName = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\Column
+     */
+    private $_column = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\TableDiff
+     */
+    private $_tableDiff = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param string $oldColumnName
+     * @param \Doctrine\DBAL\Schema\Column $column
+     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct($oldColumnName, Column $column, TableDiff $tableDiff, AbstractPlatform $platform)
+    {
+        $this->_oldColumnName = $oldColumnName;
+        $this->_column        = $column;
+        $this->_tableDiff     = $tableDiff;
+        $this->_platform      = $platform;
+    }
+
+    /**
+     * @return string
+     */
+    public function getOldColumnName()
+    {
+        return $this->_oldColumnName;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getColumn()
+    {
+        return $this->_column;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getTableDiff()
+    {
+        return $this->_tableDiff;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php	(revision 345)
@@ -0,0 +1,137 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Schema\Column;
+
+/**
+ * Event Arguments used when the portable column definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaColumnDefinitionEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Column
+     */
+    private $_column = null;
+
+    /**
+     * Raw column data as fetched from the database
+     *
+     * @var array
+     */
+    private $_tableColumn = null;
+
+    /**
+     * @var string
+     */
+    private $_table = null;
+
+    /**
+     * @var string
+     */
+    private $_database = null;
+
+    /**
+     * @var \Doctrine\DBAL\Connection
+     */
+    private $_connection = null;
+
+    /**
+     * @param array  $tableColumn
+     * @param string $table
+     * @param string $database
+     * @param \Doctrine\DBAL\Connection $conn
+     */
+    public function __construct(array $tableColumn, $table, $database, Connection $connection)
+    {
+        $this->_tableColumn = $tableColumn;
+        $this->_table       = $table;
+        $this->_database    = $database;
+        $this->_connection  = $connection;
+    }
+
+    /**
+     * Allows to clear the column which means the column will be excluded from
+     * tables column list.
+     *
+     * @param null|\Doctrine\DBAL\Schema\Column $column
+     * @return SchemaColumnDefinitionEventArgs
+     */
+    public function setColumn(Column $column = null)
+    {
+        $this->_column = $column;
+
+        return $this;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getColumn()
+    {
+        return $this->_column;
+    }
+
+    /**
+     * @return array
+     */
+    public function getTableColumn()
+    {
+        return $this->_tableColumn;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDatabase()
+    {
+        return $this->_database;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Connection
+     */
+    public function getConnection()
+    {
+        return $this->_connection;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_connection->getDatabasePlatform();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php	(revision 345)
@@ -0,0 +1,114 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * Event Arguments used when SQL queries for creating table columns are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaCreateTableColumnEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Column
+     */
+    private $_column = null;
+
+    /**
+     * @var \Doctrine\DBAL\Schema\Table
+     */
+    private $_table = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\Column $column
+     * @param \Doctrine\DBAL\Schema\Table $table
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(Column $column, Table $table, AbstractPlatform $platform)
+    {
+        $this->_column   = $column;
+        $this->_table    = $table;
+        $this->_platform = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getColumn()
+    {
+        return $this->_column;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Table
+     */
+    public function getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php	(revision 345)
@@ -0,0 +1,128 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * Event Arguments used when SQL queries for creating tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaCreateTableEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Table
+     */
+    private $_table = null;
+
+    /**
+     * @var array
+     */
+    private $_columns = null;
+
+    /**
+     * @var array
+     */
+    private $_options = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var array
+     */
+    private $_sql = array();
+
+    /**
+     * @param \Doctrine\DBAL\Schema\Table $table
+     * @param array $columns
+     * @param array $options
+     * @param Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct(Table $table, array $columns, array $options, AbstractPlatform $platform)
+    {
+        $this->_table    = $table;
+        $this->_columns  = $columns;
+        $this->_options  = $options;
+        $this->_platform = $platform;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Table
+     */
+    public function getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @return array
+     */
+    public function getColumns()
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * @return array
+     */
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string|array $sql
+     * @return \Doctrine\DBAL\Event\SchemaCreateTableEventArgs
+     */
+    public function addSql($sql)
+    {
+        if (is_array($sql)) {
+            $this->_sql = array_merge($this->_sql, $sql);
+        } else {
+            $this->_sql[] = $sql;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * Event Arguments used when the SQL query for dropping tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaDropTableEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var string|\Doctrine\DBAL\Schema\Table
+     */
+    private $_table = null;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @var string
+     */
+    private $_sql = null;
+
+    /**
+     * @param string|\Doctrine\DBAL\Schema\Table $table
+     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
+     */
+    public function __construct($table, AbstractPlatform $platform)
+    {
+        if (!$table instanceof Table && !is_string($table)) {
+            throw new \InvalidArgumentException('SchemaCreateTableEventArgs expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
+        }
+
+        $this->_table    = $table;
+        $this->_platform = $platform;
+    }
+
+    /**
+     * @return string|\Doctrine\DBAL\Schema\Table
+     */
+    public function getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * @param string $sql
+     * @return \Doctrine\DBAL\Event\SchemaDropTableEventArgs
+     */
+    public function setSql($sql)
+    {
+        $this->_sql = $sql;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaEventArgs.php	(revision 345)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\Common\EventArgs;
+
+/**
+ * Base class for schema related events.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaEventArgs extends EventArgs
+{
+    /**
+     * @var boolean
+     */
+    private $_preventDefault = false;
+
+    /**
+     * @return \Doctrine\DBAL\Event\SchemaEventArgs
+     */
+    public function preventDefault()
+    {
+        $this->_preventDefault = true;
+
+        return $this;
+    }
+
+    /**
+     * @return boolean
+     */
+    public function isDefaultPrevented()
+    {
+        return $this->_preventDefault;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php	(revision 345)
@@ -0,0 +1,122 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Schema\Index;
+
+/**
+ * Event Arguments used when the portable index definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Jan Sorgalla <jsorgalla@googlemail.com>
+ */
+class SchemaIndexDefinitionEventArgs extends SchemaEventArgs
+{
+    /**
+     * @var \Doctrine\DBAL\Schema\Index
+     */
+    private $_index = null;
+
+    /**
+     * Raw index data as fetched from the database
+     *
+     * @var array
+     */
+    private $_tableIndex = null;
+
+    /**
+     * @var string
+     */
+    private $_table = null;
+
+    /**
+     * @var \Doctrine\DBAL\Connection
+     */
+    private $_connection = null;
+
+    /**
+     * @param array  $tableIndex
+     * @param string $table
+     * @param \Doctrine\DBAL\Connection $conn
+     */
+    public function __construct(array $tableIndex, $table, Connection $connection)
+    {
+        $this->_tableIndex = $tableIndex;
+        $this->_table      = $table;
+        $this->_connection = $connection;
+    }
+
+    /**
+     * Allows to clear the index which means the index will be excluded from
+     * tables index list.
+     *
+     * @param null|\Doctrine\DBAL\Schema\Index $index
+     * @return SchemaIndexDefinitionEventArgs
+     */
+    public function setIndex(Index $index = null)
+    {
+        $this->_index = $index;
+
+        return $this;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Schema\Index
+     */
+    public function getIndex()
+    {
+        return $this->_index;
+    }
+
+    /**
+     * @return array
+     */
+    public function getTableIndex()
+    {
+        return $this->_tableIndex;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Connection
+     */
+    public function getConnection()
+    {
+        return $this->_connection;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_connection->getDatabasePlatform();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Events.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Events.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Events.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Container for all DBAL events.
+ *
+ * This class cannot be instantiated.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+final class Events
+{
+    private function __construct() {}
+
+    const postConnect = 'postConnect';
+
+    const onSchemaCreateTable             = 'onSchemaCreateTable';
+    const onSchemaCreateTableColumn       = 'onSchemaCreateTableColumn';
+    const onSchemaDropTable               = 'onSchemaDropTable';
+    const onSchemaAlterTable              = 'onSchemaAlterTable';
+    const onSchemaAlterTableAddColumn     = 'onSchemaAlterTableAddColumn';
+    const onSchemaAlterTableRemoveColumn  = 'onSchemaAlterTableRemoveColumn';
+    const onSchemaAlterTableChangeColumn  = 'onSchemaAlterTableChangeColumn';
+    const onSchemaAlterTableRenameColumn  = 'onSchemaAlterTableRenameColumn';
+    const onSchemaColumnDefinition        = 'onSchemaColumnDefinition';
+    const onSchemaIndexDefinition         = 'onSchemaIndexDefinition';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/LockMode.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/LockMode.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/LockMode.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL;
+
+/**
+ * Contains all DBAL LockModes
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class LockMode
+{
+    const NONE = 0;
+    const OPTIMISTIC = 1;
+    const PESSIMISTIC_READ = 2;
+    const PESSIMISTIC_WRITE = 4;
+
+    final private function __construct() { }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/DebugStack.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/DebugStack.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/DebugStack.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Logging;
+
+/**
+ * Includes executed SQLs in a Debug Stack
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class DebugStack implements SQLLogger
+{
+    /** @var array $queries Executed SQL queries. */
+    public $queries = array();
+
+    /** @var boolean $enabled If Debug Stack is enabled (log queries) or not. */
+    public $enabled = true;
+
+    public $start = null;
+
+    public $currentQuery = 0;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function startQuery($sql, array $params = null, array $types = null)
+    {
+        if ($this->enabled) {
+            $this->start = microtime(true);
+            $this->queries[++$this->currentQuery] = array('sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stopQuery()
+    {
+        $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/EchoSQLLogger.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/EchoSQLLogger.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/EchoSQLLogger.php	(revision 345)
@@ -0,0 +1,61 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Logging;
+
+/**
+ * A SQL logger that logs to the standard output using echo/var_dump.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EchoSQLLogger implements SQLLogger
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function startQuery($sql, array $params = null, array $types = null)
+    {
+    	echo $sql . PHP_EOL;
+
+        if ($params) {
+            var_dump($params);
+    	}
+
+        if ($types) {
+            var_dump($types);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stopQuery()
+    {
+
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/LoggerChain.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/LoggerChain.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/LoggerChain.php	(revision 345)
@@ -0,0 +1,64 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Logging;
+
+/**
+ * Chains multiple SQLLogger
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Christophe Coevoet <stof@notk.org>
+ */
+class LoggerChain implements SQLLogger
+{
+    private $loggers = array();
+
+    /**
+     * Adds a logger in the chain
+     *
+     * @param SQLLogger $logger
+     */
+    public function addLogger(SQLLogger $logger)
+    {
+        $this->loggers[] = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function startQuery($sql, array $params = null, array $types = null)
+    {
+        foreach ($this->loggers as $logger) {
+            $logger->startQuery($sql, $params, $types);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stopQuery()
+    {
+        foreach ($this->loggers as $logger) {
+            $logger->stopQuery();
+        }
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/SQLLogger.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/SQLLogger.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Logging/SQLLogger.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Logging;
+
+/**
+ * Interface for SQL loggers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface SQLLogger
+{
+    /**
+     * Logs a SQL statement somewhere.
+     *
+     * @param string $sql The SQL to be executed.
+     * @param array $params The SQL parameters.
+     * @param array $types The SQL parameter types.
+     * @return void
+     */
+    public function startQuery($sql, array $params = null, array $types = null);
+
+    /**
+     * Mark the last started query as stopped. This can be used for timing of queries.
+     *
+     * @return void
+     */
+    public function stopQuery();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/AbstractPlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/AbstractPlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/AbstractPlatform.php	(revision 345)
@@ -0,0 +1,2645 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\DBALException,
+    Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Types,
+    Doctrine\DBAL\Schema\Table,
+    Doctrine\DBAL\Schema\Index,
+    Doctrine\DBAL\Schema\ForeignKeyConstraint,
+    Doctrine\DBAL\Schema\TableDiff,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\ColumnDiff,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Events,
+    Doctrine\Common\EventManager,
+    Doctrine\DBAL\Event\SchemaCreateTableEventArgs,
+    Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs,
+    Doctrine\DBAL\Event\SchemaDropTableEventArgs,
+    Doctrine\DBAL\Event\SchemaAlterTableEventArgs,
+    Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs,
+    Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs,
+    Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs,
+    Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs;
+
+/**
+ * Base class for all DatabasePlatforms. The DatabasePlatforms are the central
+ * point of abstraction of platform-specific behaviors, features and SQL dialects.
+ * They are a passive source of information.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Remove any unnecessary methods.
+ */
+abstract class AbstractPlatform
+{
+    /**
+     * @var int
+     */
+    const CREATE_INDEXES = 1;
+
+    /**
+     * @var int
+     */
+    const CREATE_FOREIGNKEYS = 2;
+
+    /**
+     * @var int
+     */
+    const TRIM_UNSPECIFIED = 0;
+
+    /**
+     * @var int
+     */
+    const TRIM_LEADING = 1;
+
+    /**
+     * @var int
+     */
+    const TRIM_TRAILING = 2;
+
+    /**
+     * @var int
+     */
+    const TRIM_BOTH = 3;
+
+    /**
+     * @var array
+     */
+    protected $doctrineTypeMapping = null;
+
+    /**
+     * Contains a list of all columns that should generate parseable column comments for type-detection
+     * in reverse engineering scenarios.
+     *
+     * @var array
+     */
+    protected $doctrineTypeComments = null;
+
+    /**
+     * @var Doctrine\Common\EventManager
+     */
+    protected $_eventManager;
+
+    /**
+     * Constructor.
+     */
+    public function __construct() {}
+
+    /**
+     * Sets the EventManager used by the Platform.
+     *
+     * @param \Doctrine\Common\EventManager
+     */
+    public function setEventManager(EventManager $eventManager)
+    {
+        $this->_eventManager = $eventManager;
+    }
+
+    /**
+     * Gets the EventManager used by the Platform.
+     *
+     * @return \Doctrine\Common\EventManager
+     */
+    public function getEventManager()
+    {
+        return $this->_eventManager;
+    }
+
+    /**
+     * Gets the SQL snippet that declares a boolean column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    abstract public function getBooleanTypeDeclarationSQL(array $columnDef);
+
+    /**
+     * Gets the SQL snippet that declares a 4 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    abstract public function getIntegerTypeDeclarationSQL(array $columnDef);
+
+    /**
+     * Gets the SQL snippet that declares an 8 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    abstract public function getBigIntTypeDeclarationSQL(array $columnDef);
+
+    /**
+     * Gets the SQL snippet that declares a 2 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    abstract public function getSmallIntTypeDeclarationSQL(array $columnDef);
+
+    /**
+     * Gets the SQL snippet that declares common properties of an integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    abstract protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef);
+
+    /**
+     * Lazy load Doctrine Type Mappings
+     *
+     * @return void
+     */
+    abstract protected function initializeDoctrineTypeMappings();
+
+    /**
+     * Gets the SQL snippet used to declare a VARCHAR column type.
+     *
+     * @param array $field
+     */
+    public function getVarcharTypeDeclarationSQL(array $field)
+    {
+        if ( !isset($field['length'])) {
+            $field['length'] = $this->getVarcharDefaultLength();
+        }
+
+        $fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
+
+        if ($field['length'] > $this->getVarcharMaxLength()) {
+            return $this->getClobTypeDeclarationSQL($field);
+        } else {
+            return $this->getVarcharTypeDeclarationSQLSnippet($field['length'], $fixed);
+        }
+    }
+
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        throw DBALException::notSupported('VARCHARs not supported by Platform.');
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a CLOB column type.
+     *
+     * @param array $field
+     */
+    abstract public function getClobTypeDeclarationSQL(array $field);
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    abstract public function getBlobTypeDeclarationSQL(array $field);
+
+    /**
+     * Gets the name of the platform.
+     *
+     * @return string
+     */
+    abstract public function getName();
+
+    /**
+     * Register a doctrine type to be used in conjunction with a column type of this platform.
+     *
+     * @param string $dbType
+     * @param string $doctrineType
+     */
+    public function registerDoctrineTypeMapping($dbType, $doctrineType)
+    {
+        if ($this->doctrineTypeMapping === null) {
+            $this->initializeDoctrineTypeMappings();
+        }
+
+        if (!Types\Type::hasType($doctrineType)) {
+            throw DBALException::typeNotFound($doctrineType);
+        }
+
+        $dbType = strtolower($dbType);
+        $this->doctrineTypeMapping[$dbType] = $doctrineType;
+    }
+
+    /**
+     * Get the Doctrine type that is mapped for the given database column type.
+     *
+     * @param  string $dbType
+     * @return string
+     */
+    public function getDoctrineTypeMapping($dbType)
+    {
+        if ($this->doctrineTypeMapping === null) {
+            $this->initializeDoctrineTypeMappings();
+        }
+
+        $dbType = strtolower($dbType);
+        if (isset($this->doctrineTypeMapping[$dbType])) {
+            return $this->doctrineTypeMapping[$dbType];
+        } else {
+            throw new \Doctrine\DBAL\DBALException("Unknown database type ".$dbType." requested, " . get_class($this) . " may not support it.");
+        }
+    }
+
+    /**
+     * Check if a database type is currently supported by this platform.
+     *
+     * @param string $dbType
+     * @return bool
+     */
+    public function hasDoctrineTypeMappingFor($dbType)
+    {
+        if ($this->doctrineTypeMapping === null) {
+            $this->initializeDoctrineTypeMappings();
+        }
+
+        $dbType = strtolower($dbType);
+        return isset($this->doctrineTypeMapping[$dbType]);
+    }
+
+    /**
+     * Initialize the Doctrine Type comments instance variable for in_array() checks.
+     *
+     * @return void
+     */
+    protected function initializeCommentedDoctrineTypes()
+    {
+        $this->doctrineTypeComments = array(Type::TARRAY, Type::OBJECT);
+    }
+
+    /**
+     * Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type?
+     *
+     * @param Type $doctrineType
+     * @return bool
+     */
+    public function isCommentedDoctrineType(Type $doctrineType)
+    {
+        if ($this->doctrineTypeComments === null) {
+            $this->initializeCommentedDoctrineTypes();
+        }
+
+        return in_array($doctrineType->getName(), $this->doctrineTypeComments);
+    }
+
+    /**
+     * Mark this type as to be commented in ALTER TABLE and CREATE TABLE statements.
+     *
+     * @param Type $doctrineType
+     * @return void
+     */
+    public function markDoctrineTypeCommented(Type $doctrineType)
+    {
+        if ($this->doctrineTypeComments === null) {
+            $this->initializeCommentedDoctrineTypes();
+        }
+        $this->doctrineTypeComments[] = $doctrineType->getName();
+    }
+
+    /**
+     * Get the comment to append to a column comment that helps parsing this type in reverse engineering.
+     *
+     * @param Type $doctrineType
+     * @return string
+     */
+    public function getDoctrineTypeComment(Type $doctrineType)
+    {
+        return '(DC2Type:' . $doctrineType->getName() . ')';
+    }
+
+    /**
+     * Return the comment of a passed column modified by potential doctrine type comment hints.
+     *
+     * @param Column $column
+     * @return string
+     */
+    protected function getColumnComment(Column $column)
+    {
+        $comment = $column->getComment();
+        if ($this->isCommentedDoctrineType($column->getType())) {
+            $comment .= $this->getDoctrineTypeComment($column->getType());
+        }
+        return $comment;
+    }
+
+    /**
+     * Gets the character used for identifier quoting.
+     *
+     * @return string
+     */
+    public function getIdentifierQuoteCharacter()
+    {
+        return '"';
+    }
+
+    /**
+     * Gets the string portion that starts an SQL comment.
+     *
+     * @return string
+     */
+    public function getSqlCommentStartString()
+    {
+        return "--";
+    }
+
+    /**
+     * Gets the string portion that ends an SQL comment.
+     *
+     * @return string
+     */
+    public function getSqlCommentEndString()
+    {
+        return "\n";
+    }
+
+    /**
+     * Gets the maximum length of a varchar field.
+     *
+     * @return integer
+     */
+    public function getVarcharMaxLength()
+    {
+        return 4000;
+    }
+
+    /**
+     * Gets the default length of a varchar field.
+     *
+     * @return integer
+     */
+    public function getVarcharDefaultLength()
+    {
+        return 255;
+    }
+
+    /**
+     * Gets all SQL wildcard characters of the platform.
+     *
+     * @return array
+     */
+    public function getWildcards()
+    {
+        return array('%', '_');
+    }
+
+    /**
+     * Returns the regular expression operator.
+     *
+     * @return string
+     */
+    public function getRegexpExpression()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Returns global unique identifier
+     *
+     * @return string to get global unique identifier
+     */
+    public function getGuidExpression()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Returns the average value of a column
+     *
+     * @param string $column    the column to use
+     * @return string           generated sql including an AVG aggregate function
+     */
+    public function getAvgExpression($column)
+    {
+        return 'AVG(' .  $column . ')';
+    }
+
+    /**
+     * Returns the number of rows (without a NULL value) of a column
+     *
+     * If a '*' is used instead of a column the number of selected rows
+     * is returned.
+     *
+     * @param string|integer $column    the column to use
+     * @return string                   generated sql including a COUNT aggregate function
+     */
+    public function getCountExpression($column)
+    {
+        return 'COUNT(' . $column . ')';
+    }
+
+    /**
+     * Returns the highest value of a column
+     *
+     * @param string $column    the column to use
+     * @return string           generated sql including a MAX aggregate function
+     */
+    public function getMaxExpression($column)
+    {
+        return 'MAX(' . $column . ')';
+    }
+
+    /**
+     * Returns the lowest value of a column
+     *
+     * @param string $column the column to use
+     * @return string
+     */
+    public function getMinExpression($column)
+    {
+        return 'MIN(' . $column . ')';
+    }
+
+    /**
+     * Returns the total sum of a column
+     *
+     * @param string $column the column to use
+     * @return string
+     */
+    public function getSumExpression($column)
+    {
+        return 'SUM(' . $column . ')';
+    }
+
+    // scalar functions
+
+    /**
+     * Returns the md5 sum of a field.
+     *
+     * Note: Not SQL92, but common functionality
+     *
+     * @return string
+     */
+    public function getMd5Expression($column)
+    {
+        return 'MD5(' . $column . ')';
+    }
+
+    /**
+     * Returns the length of a text field.
+     *
+     * @param string $expression1
+     * @param string $expression2
+     * @return string
+     */
+    public function getLengthExpression($column)
+    {
+        return 'LENGTH(' . $column . ')';
+    }
+
+    /**
+     * Rounds a numeric field to the number of decimals specified.
+     *
+     * @param string $expression1
+     * @param string $expression2
+     * @return string
+     */
+    public function getRoundExpression($column, $decimals = 0)
+    {
+        return 'ROUND(' . $column . ', ' . $decimals . ')';
+    }
+
+    /**
+     * Returns the remainder of the division operation
+     * $expression1 / $expression2.
+     *
+     * @param string $expression1
+     * @param string $expression2
+     * @return string
+     */
+    public function getModExpression($expression1, $expression2)
+    {
+        return 'MOD(' . $expression1 . ', ' . $expression2 . ')';
+    }
+
+    /**
+     * Trim a string, leading/trailing/both and with a given char which defaults to space.
+     *
+     * @param string $str
+     * @param int $pos
+     * @param string $char has to be quoted already
+     * @return string
+     */
+    public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
+    {
+        $posStr = '';
+        $trimChar = ($char != false) ? $char . ' FROM ' : '';
+
+        if ($pos == self::TRIM_LEADING) {
+            $posStr = 'LEADING '.$trimChar;
+        } else if($pos == self::TRIM_TRAILING) {
+            $posStr = 'TRAILING '.$trimChar;
+        } else if($pos == self::TRIM_BOTH) {
+            $posStr = 'BOTH '.$trimChar;
+        }
+
+        return 'TRIM(' . $posStr . $str . ')';
+    }
+
+    /**
+     * rtrim
+     * returns the string $str with proceeding space characters removed
+     *
+     * @param string $str       literal string or column name
+     * @return string
+     */
+    public function getRtrimExpression($str)
+    {
+        return 'RTRIM(' . $str . ')';
+    }
+
+    /**
+     * ltrim
+     * returns the string $str with leading space characters removed
+     *
+     * @param string $str       literal string or column name
+     * @return string
+     */
+    public function getLtrimExpression($str)
+    {
+        return 'LTRIM(' . $str . ')';
+    }
+
+    /**
+     * upper
+     * Returns the string $str with all characters changed to
+     * uppercase according to the current character set mapping.
+     *
+     * @param string $str       literal string or column name
+     * @return string
+     */
+    public function getUpperExpression($str)
+    {
+        return 'UPPER(' . $str . ')';
+    }
+
+    /**
+     * lower
+     * Returns the string $str with all characters changed to
+     * lowercase according to the current character set mapping.
+     *
+     * @param string $str       literal string or column name
+     * @return string
+     */
+    public function getLowerExpression($str)
+    {
+        return 'LOWER(' . $str . ')';
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Returns the current system date.
+     *
+     * @return string
+     */
+    public function getNowExpression()
+    {
+        return 'NOW()';
+    }
+
+    /**
+     * return string to call a function to get a substring inside an SQL statement
+     *
+     * Note: Not SQL92, but common functionality.
+     *
+     * SQLite only supports the 2 parameter variant of this function
+     *
+     * @param  string $value         an sql string literal or column name/alias
+     * @param  integer $from     where to start the substring portion
+     * @param  integer $len       the substring portion length
+     * @return string
+     */
+    public function getSubstringExpression($value, $from, $len = null)
+    {
+        if ($len === null)
+            return 'SUBSTRING(' . $value . ' FROM ' . $from . ')';
+        else {
+            return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')';
+        }
+    }
+
+    /**
+     * Returns a series of strings concatinated
+     *
+     * concat() accepts an arbitrary number of parameters. Each parameter
+     * must contain an expression
+     *
+     * @param string $arg1, $arg2 ... $argN     strings that will be concatinated.
+     * @return string
+     */
+    public function getConcatExpression()
+    {
+        return join(' || ' , func_get_args());
+    }
+
+    /**
+     * Returns the SQL for a logical not.
+     *
+     * Example:
+     * <code>
+     * $q = new Doctrine_Query();
+     * $e = $q->expr;
+     * $q->select('*')->from('table')
+     *   ->where($e->eq('id', $e->not('null'));
+     * </code>
+     *
+     * @return string a logical expression
+     */
+    public function getNotExpression($expression)
+    {
+        return 'NOT(' . $expression . ')';
+    }
+
+    /**
+     * Returns the SQL to check if a value is one in a set of
+     * given values.
+     *
+     * in() accepts an arbitrary number of parameters. The first parameter
+     * must always specify the value that should be matched against. Successive
+     * must contain a logical expression or an array with logical expressions.
+     * These expressions will be matched against the first parameter.
+     *
+     * @param string $column        the value that should be matched against
+     * @param string|array(string)  values that will be matched against $column
+     * @return string logical expression
+     */
+    public function getInExpression($column, $values)
+    {
+        if ( ! is_array($values)) {
+            $values = array($values);
+        }
+        $values = $this->getIdentifiers($values);
+
+        if (count($values) == 0) {
+            throw \InvalidArgumentException('Values must not be empty.');
+        }
+        return $column . ' IN (' . implode(', ', $values) . ')';
+    }
+
+    /**
+     * Returns SQL that checks if a expression is null.
+     *
+     * @param string $expression the expression that should be compared to null
+     * @return string logical expression
+     */
+    public function getIsNullExpression($expression)
+    {
+        return $expression . ' IS NULL';
+    }
+
+    /**
+     * Returns SQL that checks if a expression is not null.
+     *
+     * @param string $expression the expression that should be compared to null
+     * @return string logical expression
+     */
+    public function getIsNotNullExpression($expression)
+    {
+        return $expression . ' IS NOT NULL';
+    }
+
+    /**
+     * Returns SQL that checks if an expression evaluates to a value between
+     * two values.
+     *
+     * The parameter $expression is checked if it is between $value1 and $value2.
+     *
+     * Note: There is a slight difference in the way BETWEEN works on some databases.
+     * http://www.w3schools.com/sql/sql_between.asp. If you want complete database
+     * independence you should avoid using between().
+     *
+     * @param string $expression the value to compare to
+     * @param string $value1 the lower value to compare with
+     * @param string $value2 the higher value to compare with
+     * @return string logical expression
+     */
+    public function getBetweenExpression($expression, $value1, $value2)
+    {
+        return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2;
+    }
+
+    public function getAcosExpression($value)
+    {
+        return 'ACOS(' . $value . ')';
+    }
+
+    public function getSinExpression($value)
+    {
+        return 'SIN(' . $value . ')';
+    }
+
+    public function getPiExpression()
+    {
+        return 'PI()';
+    }
+
+    public function getCosExpression($value)
+    {
+        return 'COS(' . $value . ')';
+    }
+
+    /**
+     * Calculate the difference in days between the two passed dates.
+     *
+     * Computes diff = date1 - date2
+     *
+     * @param string $date1
+     * @param string $date2
+     * @return string
+     */
+    public function getDateDiffExpression($date1, $date2)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Add the number of given days to a date.
+     *
+     * @param string $date
+     * @param int $days
+     * @return string
+     */
+    public function getDateAddDaysExpression($date, $days)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Substract the number of given days to a date.
+     *
+     * @param string $date
+     * @param int $days
+     * @return string
+     */
+    public function getDateSubDaysExpression($date, $days)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Add the number of given months to a date.
+     *
+     * @param string $date
+     * @param int $months
+     * @return string
+     */
+    public function getDateAddMonthExpression($date, $months)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Substract the number of given months to a date.
+     *
+     * @param string $date
+     * @param int $months
+     * @return string
+     */
+    public function getDateSubMonthExpression($date, $months)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Gets SQL bit AND comparison  expression
+     *
+     * @param   string $value1
+     * @param   string $value2
+     * @return  string
+     */
+    public function getBitAndComparisonExpression($value1, $value2)
+    {
+        return '(' . $value1 . ' & ' . $value2 . ')';
+    }
+
+    /**
+     * Gets SQL bit OR comparison expression
+     *
+     * @param   string $value1
+     * @param   string $value2
+     * @return  string
+     */
+    public function getBitOrComparisonExpression($value1, $value2)
+    {
+        return '(' . $value1 . ' | ' . $value2 . ')';
+    }
+
+    public function getForUpdateSQL()
+    {
+        return 'FOR UPDATE';
+    }
+
+    /**
+     * Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification.
+     *
+     * @param  string $fromClause
+     * @param  int $lockMode
+     * @return string
+     */
+    public function appendLockHint($fromClause, $lockMode)
+    {
+        return $fromClause;
+    }
+
+    /**
+     * Get the sql snippet to append to any SELECT statement which locks rows in shared read lock.
+     *
+     * This defaults to the ASNI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database
+     * vendors allow to lighten this constraint up to be a real read lock.
+     *
+     * @return string
+     */
+    public function getReadLockSQL()
+    {
+        return $this->getForUpdateSQL();
+    }
+
+    /**
+     * Get the SQL snippet to append to any SELECT statement which obtains an exclusive lock on the rows.
+     *
+     * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ASNI SQL standard.
+     *
+     * @return string
+     */
+    public function getWriteLockSQL()
+    {
+        return $this->getForUpdateSQL();
+    }
+
+    public function getDropDatabaseSQL($database)
+    {
+        return 'DROP DATABASE ' . $database;
+    }
+
+    /**
+     * Drop a Table
+     *
+     * @throws \InvalidArgumentException
+     * @param  Table|string $table
+     * @return string
+     */
+    public function getDropTableSQL($table)
+    {
+        $tableArg = $table;
+
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        } else if(!is_string($table)) {
+            throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
+        }
+
+        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) {
+            $eventArgs = new SchemaDropTableEventArgs($tableArg, $this);
+            $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs);
+
+            if ($eventArgs->isDefaultPrevented()) {
+                return $eventArgs->getSql();
+            }
+        }
+
+        return 'DROP TABLE ' . $table;
+    }
+
+    /**
+     * Get SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction.
+     *
+     * @param Table|string $table
+     * @return string
+     */
+    public function getDropTemporaryTableSQL($table)
+    {
+        return $this->getDropTableSQL($table);
+    }
+
+    /**
+     * Drop index from a table
+     *
+     * @param Index|string $name
+     * @param string|Table $table
+     * @return string
+     */
+    public function getDropIndexSQL($index, $table=null)
+    {
+        if($index instanceof \Doctrine\DBAL\Schema\Index) {
+            $index = $index->getQuotedName($this);
+        } else if(!is_string($index)) {
+            throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
+        }
+
+        return 'DROP INDEX ' . $index;
+    }
+
+    /**
+     * Get drop constraint sql
+     *
+     * @param  \Doctrine\DBAL\Schema\Constraint $constraint
+     * @param  string|Table $table
+     * @return string
+     */
+    public function getDropConstraintSQL($constraint, $table)
+    {
+        if ($constraint instanceof \Doctrine\DBAL\Schema\Constraint) {
+            $constraint = $constraint->getQuotedName($this);
+        }
+
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint;
+    }
+
+    /**
+     * @param  ForeignKeyConstraint|string $foreignKey
+     * @param  Table|string $table
+     * @return string
+     */
+    public function getDropForeignKeySQL($foreignKey, $table)
+    {
+        if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
+            $foreignKey = $foreignKey->getQuotedName($this);
+        }
+
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey;
+    }
+
+    /**
+     * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
+     * on this platform.
+     *
+     * @param string $table The name of the table.
+     * @param int $createFlags
+     * @return array The sequence of SQL statements.
+     */
+    public function getCreateTableSQL(Table $table, $createFlags=self::CREATE_INDEXES)
+    {
+        if ( ! is_int($createFlags)) {
+            throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.");
+        }
+
+        if (count($table->getColumns()) == 0) {
+            throw DBALException::noColumnsSpecifiedForTable($table->getName());
+        }
+
+        $tableName = $table->getQuotedName($this);
+        $options = $table->getOptions();
+        $options['uniqueConstraints'] = array();
+        $options['indexes'] = array();
+        $options['primary'] = array();
+
+        if (($createFlags&self::CREATE_INDEXES) > 0) {
+            foreach ($table->getIndexes() AS $index) {
+                /* @var $index Index */
+                if ($index->isPrimary()) {
+                    $options['primary'] = $index->getColumns();
+                } else {
+                    $options['indexes'][$index->getName()] = $index;
+                }
+            }
+        }
+
+        $columnSql = array();
+        $columns = array();
+        foreach ($table->getColumns() AS $column) {
+            /* @var \Doctrine\DBAL\Schema\Column $column */
+
+            if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
+                $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
+                $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
+
+                $columnSql = array_merge($columnSql, $eventArgs->getSql());
+
+                if ($eventArgs->isDefaultPrevented()) {
+                    continue;
+                }
+            }
+
+            $columnData = array();
+            $columnData['name'] = $column->getQuotedName($this);
+            $columnData['type'] = $column->getType();
+            $columnData['length'] = $column->getLength();
+            $columnData['notnull'] = $column->getNotNull();
+            $columnData['fixed'] = $column->getFixed();
+            $columnData['unique'] = false; // TODO: what do we do about this?
+            $columnData['version'] = ($column->hasPlatformOption("version"))?$column->getPlatformOption('version'):false;
+            if(strtolower($columnData['type']) == "string" && $columnData['length'] === null) {
+                $columnData['length'] = 255;
+            }
+            $columnData['unsigned'] = $column->getUnsigned();
+            $columnData['precision'] = $column->getPrecision();
+            $columnData['scale'] = $column->getScale();
+            $columnData['default'] = $column->getDefault();
+            $columnData['columnDefinition'] = $column->getColumnDefinition();
+            $columnData['autoincrement'] = $column->getAutoincrement();
+            $columnData['comment'] = $this->getColumnComment($column);
+
+            if(in_array($column->getName(), $options['primary'])) {
+                $columnData['primary'] = true;
+            }
+
+            $columns[$columnData['name']] = $columnData;
+        }
+
+        if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) {
+            $options['foreignKeys'] = array();
+            foreach ($table->getForeignKeys() AS $fkConstraint) {
+                $options['foreignKeys'][] = $fkConstraint;
+            }
+        }
+
+        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
+            $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
+            $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
+
+            if ($eventArgs->isDefaultPrevented()) {
+                return array_merge($eventArgs->getSql(), $columnSql);
+            }
+        }
+
+        $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
+        if ($this->supportsCommentOnStatement()) {
+            foreach ($table->getColumns() AS $column) {
+                if ($this->getColumnComment($column)) {
+                    $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getName(), $this->getColumnComment($column));
+                }
+            }
+        }
+
+        return array_merge($sql, $columnSql);
+    }
+
+    public function getCommentOnColumnSQL($tableName, $columnName, $comment)
+    {
+        return "COMMENT ON COLUMN " . $tableName . "." . $columnName . " IS '" . $comment . "'";
+    }
+
+    /**
+     * @param string $tableName
+     * @param array $columns
+     * @param array $options
+     * @return array
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        $columnListSql = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+            foreach ($options['uniqueConstraints'] as $name => $definition) {
+                $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
+            }
+        }
+
+        if (isset($options['primary']) && ! empty($options['primary'])) {
+            $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
+        }
+
+        if (isset($options['indexes']) && ! empty($options['indexes'])) {
+            foreach($options['indexes'] as $index => $definition) {
+                $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
+            }
+        }
+
+        $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
+
+        $check = $this->getCheckDeclarationSQL($columns);
+        if ( ! empty($check)) {
+            $query .= ', ' . $check;
+        }
+        $query .= ')';
+
+        $sql[] = $query;
+
+        if (isset($options['foreignKeys'])) {
+            foreach ((array) $options['foreignKeys'] AS $definition) {
+                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
+            }
+        }
+
+        return $sql;
+    }
+
+    public function getCreateTemporaryTableSnippetSQL()
+    {
+        return "CREATE TEMPORARY TABLE";
+    }
+
+    /**
+     * Gets the SQL to create a sequence on this platform.
+     *
+     * @param \Doctrine\DBAL\Schema\Sequence $sequence
+     * @throws DBALException
+     */
+    public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Gets the SQL statement to change a sequence on this platform.
+     *
+     * @param \Doctrine\DBAL\Schema\Sequence $sequence
+     * @return string
+     */
+    public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Gets the SQL to create a constraint on a table on this platform.
+     *
+     * @param Constraint $constraint
+     * @param string|Table $table
+     * @return string
+     */
+    public function getCreateConstraintSQL(\Doctrine\DBAL\Schema\Constraint $constraint, $table)
+    {
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this);
+
+        $columns = array();
+        foreach ($constraint->getColumns() as $column) {
+            $columns[] = $column;
+        }
+        $columnList = '('. implode(', ', $columns) . ')';
+
+        $referencesClause = '';
+        if ($constraint instanceof \Doctrine\DBAL\Schema\Index) {
+            if($constraint->isPrimary()) {
+                $query .= ' PRIMARY KEY';
+            } elseif ($constraint->isUnique()) {
+                $query .= ' UNIQUE';
+            } else {
+                throw new \InvalidArgumentException(
+                    'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().'
+                );
+            }
+        } else if ($constraint instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
+            $query .= ' FOREIGN KEY';
+
+            $foreignColumns = array();
+            foreach ($constraint->getForeignColumns() AS $column) {
+                $foreignColumns[] = $column;
+            }
+
+            $referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')';
+        }
+        $query .= ' '.$columnList.$referencesClause;
+
+        return $query;
+    }
+
+    /**
+     * Gets the SQL to create an index on a table on this platform.
+     *
+     * @param Index $index
+     * @param string|Table $table name of the table on which the index is to be created
+     * @return string
+     */
+    public function getCreateIndexSQL(Index $index, $table)
+    {
+        if ($table instanceof Table) {
+            $table = $table->getQuotedName($this);
+        }
+        $name = $index->getQuotedName($this);
+        $columns = $index->getColumns();
+
+        if (count($columns) == 0) {
+            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
+        }
+
+        if ($index->isPrimary()) {
+            return $this->getCreatePrimaryKeySQL($index, $table);
+        } else {
+            $type = '';
+            if ($index->isUnique()) {
+                $type = 'UNIQUE ';
+            }
+
+            $query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table;
+            $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')';
+        }
+
+        return $query;
+    }
+
+    /**
+     * Get SQL to create an unnamed primary key constraint.
+     *
+     * @param Index $index
+     * @param string|Table $table
+     * @return string
+     */
+    public function getCreatePrimaryKeySQL(Index $index, $table)
+    {
+        return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getColumns()) . ')';
+    }
+
+    /**
+     * Quotes a string so that it can be safely used as a table or column name,
+     * even if it is a reserved word of the platform. This also detects identifier
+     * chains seperated by dot and quotes them independently.
+     *
+     * NOTE: Just because you CAN use quoted identifiers doesn't mean
+     * you SHOULD use them.  In general, they end up causing way more
+     * problems than they solve.
+     *
+     * @param string $str           identifier name to be quoted
+     * @return string               quoted identifier string
+     */
+    public function quoteIdentifier($str)
+    {
+        if (strpos($str, ".") !== false) {
+            $parts = array_map(array($this, "quoteIdentifier"), explode(".", $str));
+            return implode(".", $parts);
+        }
+
+        return $this->quoteSingleIdentifier($str);
+    }
+
+    /**
+     * Quote a single identifier (no dot chain seperation)
+     *
+     * @param string $str
+     * @return string
+     */
+    public function quoteSingleIdentifier($str)
+    {
+        $c = $this->getIdentifierQuoteCharacter();
+
+        return $c . str_replace($c, $c.$c, $str) . $c;
+    }
+
+    /**
+     * Create a new foreign key
+     *
+     * @param ForeignKeyConstraint  $foreignKey    ForeignKey instance
+     * @param string|Table          $table         name of the table on which the foreign key is to be created
+     * @return string
+     */
+    public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
+    {
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        $query = 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSQL($foreignKey);
+
+        return $query;
+    }
+
+    /**
+     * Gets the sql statements for altering an existing table.
+     *
+     * The method returns an array of sql statements, since some platforms need several statements.
+     *
+     * @param TableDiff $diff
+     * @return array
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * @param Column $column
+     * @param TableDiff $diff
+     * @param array $columnSql
+     */
+    protected function onSchemaAlterTableAddColumn(Column $column, TableDiff $diff, &$columnSql)
+    {
+        if (null === $this->_eventManager) {
+            return false;
+        }
+
+        if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableAddColumn)) {
+            return false;
+        }
+
+        $eventArgs = new SchemaAlterTableAddColumnEventArgs($column, $diff, $this);
+        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableAddColumn, $eventArgs);
+
+        $columnSql = array_merge($columnSql, $eventArgs->getSql());
+
+        return $eventArgs->isDefaultPrevented();
+    }
+
+    /**
+     * @param Column $column
+     * @param TableDiff $diff
+     * @param array $columnSql
+     */
+    protected function onSchemaAlterTableRemoveColumn(Column $column, TableDiff $diff, &$columnSql)
+    {
+        if (null === $this->_eventManager) {
+            return false;
+        }
+
+        if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableRemoveColumn)) {
+            return false;
+        }
+
+        $eventArgs = new SchemaAlterTableRemoveColumnEventArgs($column, $diff, $this);
+        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRemoveColumn, $eventArgs);
+
+        $columnSql = array_merge($columnSql, $eventArgs->getSql());
+
+        return $eventArgs->isDefaultPrevented();
+    }
+
+    /**
+     * @param ColumnDiff $columnDiff
+     * @param TableDiff $diff
+     * @param array $columnSql
+     */
+    protected function onSchemaAlterTableChangeColumn(ColumnDiff $columnDiff, TableDiff $diff, &$columnSql)
+    {
+        if (null === $this->_eventManager) {
+            return false;
+        }
+
+        if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableChangeColumn)) {
+            return false;
+        }
+
+        $eventArgs = new SchemaAlterTableChangeColumnEventArgs($columnDiff, $diff, $this);
+        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableChangeColumn, $eventArgs);
+
+        $columnSql = array_merge($columnSql, $eventArgs->getSql());
+
+        return $eventArgs->isDefaultPrevented();
+    }
+
+    /**
+     * @param string $oldColumnName
+     * @param Column $column
+     * @param TableDiff $diff
+     * @param array $columnSql
+     */
+    protected function onSchemaAlterTableRenameColumn($oldColumnName, Column $column, TableDiff $diff, &$columnSql)
+    {
+        if (null === $this->_eventManager) {
+            return false;
+        }
+
+        if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableRenameColumn)) {
+            return false;
+        }
+
+        $eventArgs = new SchemaAlterTableRenameColumnEventArgs($oldColumnName, $column, $diff, $this);
+        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRenameColumn, $eventArgs);
+
+        $columnSql = array_merge($columnSql, $eventArgs->getSql());
+
+        return $eventArgs->isDefaultPrevented();
+    }
+    /**
+     * @param TableDiff $diff
+     * @param array $columnSql
+     */
+    protected function onSchemaAlterTable(TableDiff $diff, &$sql)
+    {
+        if (null === $this->_eventManager) {
+            return false;
+        }
+
+        if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTable)) {
+            return false;
+        }
+
+        $eventArgs = new SchemaAlterTableEventArgs($diff, $this);
+        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs);
+
+        $sql = array_merge($sql, $eventArgs->getSql());
+
+        return $eventArgs->isDefaultPrevented();
+    }
+
+    protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
+    {
+        $tableName = $diff->name;
+
+        $sql = array();
+        if ($this->supportsForeignKeyConstraints()) {
+            foreach ($diff->removedForeignKeys AS $foreignKey) {
+                $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
+            }
+            foreach ($diff->changedForeignKeys AS $foreignKey) {
+                $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
+            }
+        }
+
+        foreach ($diff->removedIndexes AS $index) {
+            $sql[] = $this->getDropIndexSQL($index, $tableName);
+        }
+        foreach ($diff->changedIndexes AS $index) {
+            $sql[] = $this->getDropIndexSQL($index, $tableName);
+        }
+
+        return $sql;
+    }
+
+    protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
+    {
+        if ($diff->newName !== false) {
+            $tableName = $diff->newName;
+        } else {
+            $tableName = $diff->name;
+        }
+
+        $sql = array();
+        if ($this->supportsForeignKeyConstraints()) {
+            foreach ($diff->addedForeignKeys AS $foreignKey) {
+                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
+            }
+            foreach ($diff->changedForeignKeys AS $foreignKey) {
+                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
+            }
+        }
+
+        foreach ($diff->addedIndexes AS $index) {
+            $sql[] = $this->getCreateIndexSQL($index, $tableName);
+        }
+        foreach ($diff->changedIndexes AS $index) {
+            $sql[] = $this->getCreateIndexSQL($index, $tableName);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
+     *
+     * @param TableDiff $diff
+     * @return array
+     */
+    protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
+    {
+        return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff));
+    }
+
+    /**
+     * Get declaration of a number of fields in bulk
+     *
+     * @param array $fields  a multidimensional associative array.
+     *      The first dimension determines the field name, while the second
+     *      dimension is keyed with the name of the properties
+     *      of the field being declared as array indexes. Currently, the types
+     *      of supported field properties are as follows:
+     *
+     *      length
+     *          Integer value that determines the maximum length of the text
+     *          field. If this argument is missing the field should be
+     *          declared to have the longest length allowed by the DBMS.
+     *
+     *      default
+     *          Text value to be used as default for this field.
+     *
+     *      notnull
+     *          Boolean flag that indicates whether this field is constrained
+     *          to not be set to null.
+     *      charset
+     *          Text value with the default CHARACTER SET for this field.
+     *      collation
+     *          Text value with the default COLLATION for this field.
+     *      unique
+     *          unique constraint
+     *
+     * @return string
+     */
+    public function getColumnDeclarationListSQL(array $fields)
+    {
+        $queryFields = array();
+        foreach ($fields as $fieldName => $field) {
+            $query = $this->getColumnDeclarationSQL($fieldName, $field);
+            $queryFields[] = $query;
+        }
+        return implode(', ', $queryFields);
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to declare a generic type
+     * field to be used in statements like CREATE TABLE.
+     *
+     * @param string $name   name the field to be declared.
+     * @param array  $field  associative array with the name of the properties
+     *      of the field being declared as array indexes. Currently, the types
+     *      of supported field properties are as follows:
+     *
+     *      length
+     *          Integer value that determines the maximum length of the text
+     *          field. If this argument is missing the field should be
+     *          declared to have the longest length allowed by the DBMS.
+     *
+     *      default
+     *          Text value to be used as default for this field.
+     *
+     *      notnull
+     *          Boolean flag that indicates whether this field is constrained
+     *          to not be set to null.
+     *      charset
+     *          Text value with the default CHARACTER SET for this field.
+     *      collation
+     *          Text value with the default COLLATION for this field.
+     *      unique
+     *          unique constraint
+     *      check
+     *          column check constraint
+     *      columnDefinition
+     *          a string that defines the complete column
+     *
+     * @return string  DBMS specific SQL code portion that should be used to declare the column.
+     */
+    public function getColumnDeclarationSQL($name, array $field)
+    {
+        if (isset($field['columnDefinition'])) {
+            $columnDef = $this->getCustomTypeDeclarationSQL($field);
+        } else {
+            $default = $this->getDefaultValueDeclarationSQL($field);
+
+            $charset = (isset($field['charset']) && $field['charset']) ?
+                    ' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
+
+            $collation = (isset($field['collation']) && $field['collation']) ?
+                    ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
+
+            $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
+
+            $unique = (isset($field['unique']) && $field['unique']) ?
+                    ' ' . $this->getUniqueFieldDeclarationSQL() : '';
+
+            $check = (isset($field['check']) && $field['check']) ?
+                    ' ' . $field['check'] : '';
+
+            $typeDecl = $field['type']->getSqlDeclaration($field, $this);
+            $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
+        }
+
+        if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment']) {
+            $columnDef .= " COMMENT '" . $field['comment'] . "'";
+        }
+
+        return $name . ' ' . $columnDef;
+    }
+
+    /**
+     * Gets the SQL snippet that declares a floating point column of arbitrary precision.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    public function getDecimalTypeDeclarationSQL(array $columnDef)
+    {
+        $columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision']))
+            ? 10 : $columnDef['precision'];
+        $columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale']))
+            ? 0 : $columnDef['scale'];
+
+        return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')';
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set a default value
+     * declaration to be used in statements like CREATE TABLE.
+     *
+     * @param array $field      field definition array
+     * @return string           DBMS specific SQL code portion needed to set a default value
+     */
+    public function getDefaultValueDeclarationSQL($field)
+    {
+        $default = empty($field['notnull']) ? ' DEFAULT NULL' : '';
+
+        if (isset($field['default'])) {
+            $default = " DEFAULT '".$field['default']."'";
+            if (isset($field['type'])) {
+                if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) {
+                    $default = " DEFAULT ".$field['default'];
+                } else if ((string)$field['type'] == 'DateTime' && $field['default'] == $this->getCurrentTimestampSQL()) {
+                    $default = " DEFAULT ".$this->getCurrentTimestampSQL();
+
+                } else if ((string) $field['type'] == 'Boolean') {
+                    $default = " DEFAULT '" . $this->convertBooleans($field['default']) . "'";
+                }
+            }
+        }
+        return $default;
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set a CHECK constraint
+     * declaration to be used in statements like CREATE TABLE.
+     *
+     * @param array $definition     check definition
+     * @return string               DBMS specific SQL code portion needed to set a CHECK constraint
+     */
+    public function getCheckDeclarationSQL(array $definition)
+    {
+        $constraints = array();
+        foreach ($definition as $field => $def) {
+            if (is_string($def)) {
+                $constraints[] = 'CHECK (' . $def . ')';
+            } else {
+                if (isset($def['min'])) {
+                    $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')';
+                }
+
+                if (isset($def['max'])) {
+                    $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')';
+                }
+            }
+        }
+
+        return implode(', ', $constraints);
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set a unique
+     * constraint declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $name          name of the unique constraint
+     * @param Index $index          index definition
+     * @return string               DBMS specific SQL code portion needed
+     *                              to set a constraint
+     */
+    public function getUniqueConstraintDeclarationSQL($name, Index $index)
+    {
+        if (count($index->getColumns()) == 0) {
+            throw \InvalidArgumentException("Incomplete definition. 'columns' required.");
+        }
+
+        return 'CONSTRAINT ' . $name . ' UNIQUE ('
+             . $this->getIndexFieldDeclarationListSQL($index->getColumns())
+             . ')';
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set an index
+     * declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $name          name of the index
+     * @param Index $index          index definition
+     * @return string               DBMS specific SQL code portion needed to set an index
+     */
+    public function getIndexDeclarationSQL($name, Index $index)
+    {
+        $type = '';
+
+        if($index->isUnique()) {
+            $type = 'UNIQUE ';
+        }
+
+        if (count($index->getColumns()) == 0) {
+            throw \InvalidArgumentException("Incomplete definition. 'columns' required.");
+        }
+
+        return $type . 'INDEX ' . $name . ' ('
+             . $this->getIndexFieldDeclarationListSQL($index->getColumns())
+             . ')';
+    }
+
+    /**
+     * getCustomTypeDeclarationSql
+     * Obtail SQL code portion needed to create a custom column,
+     * e.g. when a field has the "columnDefinition" keyword.
+     * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate.
+     *
+     * @return string
+     */
+    public function getCustomTypeDeclarationSQL(array $columnDef)
+    {
+        return $columnDef['columnDefinition'];
+    }
+
+    /**
+     * getIndexFieldDeclarationList
+     * Obtain DBMS specific SQL code portion needed to set an index
+     * declaration to be used in statements like CREATE TABLE.
+     *
+     * @return string
+     */
+    public function getIndexFieldDeclarationListSQL(array $fields)
+    {
+        $ret = array();
+        foreach ($fields as $field => $definition) {
+            if (is_array($definition)) {
+                $ret[] = $field;
+            } else {
+                $ret[] = $definition;
+            }
+        }
+        return implode(', ', $ret);
+    }
+
+    /**
+     * A method to return the required SQL string that fits between CREATE ... TABLE
+     * to create the table as a temporary table.
+     *
+     * Should be overridden in driver classes to return the correct string for the
+     * specific database type.
+     *
+     * The default is to return the string "TEMPORARY" - this will result in a
+     * SQL error for any database that does not support temporary tables, or that
+     * requires a different SQL command from "CREATE TEMPORARY TABLE".
+     *
+     * @return string The string required to be placed between "CREATE" and "TABLE"
+     *                to generate a temporary table, if possible.
+     */
+    public function getTemporaryTableSQL()
+    {
+        return 'TEMPORARY';
+    }
+
+    /**
+     * Some vendors require temporary table names to be qualified specially.
+     *
+     * @param  string $tableName
+     * @return string
+     */
+    public function getTemporaryTableName($tableName)
+    {
+        return $tableName;
+    }
+
+    /**
+     * Get sql query to show a list of database.
+     *
+     * @return string
+     */
+    public function getShowDatabasesSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @param array $definition         an associative array with the following structure:
+     *          name                    optional constraint name
+     *
+     *          local                   the local field(s)
+     *
+     *          foreign                 the foreign reference field(s)
+     *
+     *          foreignTable            the name of the foreign table
+     *
+     *          onDelete                referential delete action
+     *
+     *          onUpdate                referential update action
+     *
+     *          deferred                deferred constraint checking
+     *
+     * The onDelete and onUpdate keys accept the following values:
+     *
+     * CASCADE: Delete or update the row from the parent table and automatically delete or
+     *          update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
+     *          Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column
+     *          in the parent table or in the child table.
+     *
+     * SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the
+     *          child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier
+     *          specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
+     *
+     * NO ACTION: In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary
+     *           key value is not allowed to proceed if there is a related foreign key value in the referenced table.
+     *
+     * RESTRICT: Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as
+     *           omitting the ON DELETE or ON UPDATE clause.
+     *
+     * SET DEFAULT
+     *
+     * @return string  DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
+     *                 of a field declaration.
+     */
+    public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
+    {
+        $sql  = $this->getForeignKeyBaseDeclarationSQL($foreignKey);
+        $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey);
+
+        return $sql;
+    }
+
+    /**
+     * Return the FOREIGN KEY query section dealing with non-standard options
+     * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
+     *
+     * @param ForeignKeyConstraint $foreignKey     foreign key definition
+     * @return string
+     */
+    public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
+    {
+        $query = '';
+        if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) {
+            $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate'));
+        }
+        if ($foreignKey->hasOption('onDelete')) {
+            $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete'));
+        }
+        return $query;
+    }
+
+    /**
+     * returns given referential action in uppercase if valid, otherwise throws
+     * an exception
+     *
+     * @throws Doctrine_Exception_Exception     if unknown referential action given
+     * @param string $action    foreign key referential action
+     * @param string            foreign key referential action in uppercase
+     */
+    public function getForeignKeyReferentialActionSQL($action)
+    {
+        $upper = strtoupper($action);
+        switch ($upper) {
+            case 'CASCADE':
+            case 'SET NULL':
+            case 'NO ACTION':
+            case 'RESTRICT':
+            case 'SET DEFAULT':
+                return $upper;
+            break;
+            default:
+                throw new \InvalidArgumentException('Invalid foreign key action: ' . $upper);
+        }
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @param ForeignKeyConstraint $foreignKey
+     * @return string
+     */
+    public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey)
+    {
+        $sql = '';
+        if (strlen($foreignKey->getName())) {
+            $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' ';
+        }
+        $sql .= 'FOREIGN KEY (';
+
+        if (count($foreignKey->getLocalColumns()) == 0) {
+            throw new \InvalidArgumentException("Incomplete definition. 'local' required.");
+        }
+        if (count($foreignKey->getForeignColumns()) == 0) {
+            throw new \InvalidArgumentException("Incomplete definition. 'foreign' required.");
+        }
+        if (strlen($foreignKey->getForeignTableName()) == 0) {
+            throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
+        }
+
+        $sql .= implode(', ', $foreignKey->getLocalColumns())
+              . ') REFERENCES '
+              . $foreignKey->getForeignTableName() . ' ('
+              . implode(', ', $foreignKey->getForeignColumns()) . ')';
+
+        return $sql;
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the UNIQUE constraint
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @return string  DBMS specific SQL code portion needed to set the UNIQUE constraint
+     *                 of a field declaration.
+     */
+    public function getUniqueFieldDeclarationSQL()
+    {
+        return 'UNIQUE';
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $charset   name of the charset
+     * @return string  DBMS specific SQL code portion needed to set the CHARACTER SET
+     *                 of a field declaration.
+     */
+    public function getColumnCharsetDeclarationSQL($charset)
+    {
+        return '';
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the COLLATION
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $collation   name of the collation
+     * @return string  DBMS specific SQL code portion needed to set the COLLATION
+     *                 of a field declaration.
+     */
+    public function getColumnCollationDeclarationSQL($collation)
+    {
+        return '';
+    }
+
+    /**
+     * Whether the platform prefers sequences for ID generation.
+     * Subclasses should override this method to return TRUE if they prefer sequences.
+     *
+     * @return boolean
+     */
+    public function prefersSequences()
+    {
+        return false;
+    }
+
+    /**
+     * Whether the platform prefers identity columns (eg. autoincrement) for ID generation.
+     * Subclasses should override this method to return TRUE if they prefer identity columns.
+     *
+     * @return boolean
+     */
+    public function prefersIdentityColumns()
+    {
+        return false;
+    }
+
+    /**
+     * Some platforms need the boolean values to be converted.
+     *
+     * The default conversion in this implementation converts to integers (false => 0, true => 1).
+     *
+     * @param mixed $item
+     */
+    public function convertBooleans($item)
+    {
+        if (is_array($item)) {
+            foreach ($item as $k => $value) {
+                if (is_bool($value)) {
+                    $item[$k] = (int) $value;
+                }
+            }
+        } else if (is_bool($item)) {
+            $item = (int) $item;
+        }
+        return $item;
+    }
+
+    /**
+     * Gets the SQL statement specific for the platform to set the charset.
+     *
+     * This function is MySQL specific and required by
+     * {@see \Doctrine\DBAL\Connection::setCharset($charset)}
+     *
+     * @param string $charset
+     * @return string
+     */
+    public function getSetCharsetSQL($charset)
+    {
+        return "SET NAMES '".$charset."'";
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current date.
+     *
+     * @return string
+     */
+    public function getCurrentDateSQL()
+    {
+        return 'CURRENT_DATE';
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current time.
+     *
+     * @return string
+     */
+    public function getCurrentTimeSQL()
+    {
+        return 'CURRENT_TIME';
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current timestamp
+     *
+     * @return string
+     */
+    public function getCurrentTimestampSQL()
+    {
+        return 'CURRENT_TIMESTAMP';
+    }
+
+    /**
+     * Get sql for transaction isolation level Connection constant
+     *
+     * @param integer $level
+     */
+    protected function _getTransactionIsolationLevelSQL($level)
+    {
+        switch ($level) {
+            case Connection::TRANSACTION_READ_UNCOMMITTED:
+                return 'READ UNCOMMITTED';
+            case Connection::TRANSACTION_READ_COMMITTED:
+                return 'READ COMMITTED';
+            case Connection::TRANSACTION_REPEATABLE_READ:
+                return 'REPEATABLE READ';
+            case Connection::TRANSACTION_SERIALIZABLE:
+                return 'SERIALIZABLE';
+            default:
+                throw new \InvalidArgumentException('Invalid isolation level:' . $level);
+        }
+    }
+
+    public function getListDatabasesSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListSequencesSQL($database)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListTablesSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListUsersSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Get the SQL to list all views of a database or user.
+     *
+     * @param string $database
+     * @return string
+     */
+    public function getListViewsSQL($database)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Get the list of indexes for the current database.
+     *
+     * The current database parameter is optional but will always be passed
+     * when using the SchemaManager API and is the database the given table is in.
+     *
+     * Attention: Some platforms only support currentDatabase when they
+     * are connected with that database. Cross-database information schema
+     * requests may be impossible.
+     *
+     * @param string $table
+     * @param string $currentDatabase
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListTableForeignKeysSQL($table)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getDropViewSQL($name)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getDropSequenceSQL($sequence)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getSequenceNextValSQL($sequenceName)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getCreateDatabaseSQL($database)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Get sql to set the transaction isolation level
+     *
+     * @param integer $level
+     */
+    public function getSetTransactionIsolationSQL($level)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create datetime fields in
+     * statements like CREATE TABLE
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create datetime with timezone offset fields.
+     *
+     * @param array $fieldDeclaration
+     */
+    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration);
+    }
+
+
+    /**
+     * Obtain DBMS specific SQL to be used to create date fields in statements
+     * like CREATE TABLE.
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create time fields in statements
+     * like CREATE TABLE.
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getFloatDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DOUBLE PRECISION';
+    }
+
+    /**
+     * Gets the default transaction isolation level of the platform.
+     *
+     * @return integer The default isolation level.
+     * @see Doctrine\DBAL\Connection\TRANSACTION_* constants.
+     */
+    public function getDefaultTransactionIsolationLevel()
+    {
+        return Connection::TRANSACTION_READ_COMMITTED;
+    }
+
+    /* supports*() methods */
+
+    /**
+     * Whether the platform supports sequences.
+     *
+     * @return boolean
+     */
+    public function supportsSequences()
+    {
+        return false;
+    }
+
+    /**
+     * Whether the platform supports identity columns.
+     * Identity columns are columns that recieve an auto-generated value from the
+     * database on insert of a row.
+     *
+     * @return boolean
+     */
+    public function supportsIdentityColumns()
+    {
+        return false;
+    }
+
+    /**
+     * Whether the platform supports indexes.
+     *
+     * @return boolean
+     */
+    public function supportsIndexes()
+    {
+        return true;
+    }
+
+    public function supportsAlterTable()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports transactions.
+     *
+     * @return boolean
+     */
+    public function supportsTransactions()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports savepoints.
+     *
+     * @return boolean
+     */
+    public function supportsSavepoints()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports releasing savepoints.
+     *
+     * @return boolean
+     */
+    public function supportsReleaseSavepoints()
+    {
+        return $this->supportsSavepoints();
+    }
+
+    /**
+     * Whether the platform supports primary key constraints.
+     *
+     * @return boolean
+     */
+    public function supportsPrimaryConstraints()
+    {
+        return true;
+    }
+
+    /**
+     * Does the platform supports foreign key constraints?
+     *
+     * @return boolean
+     */
+    public function supportsForeignKeyConstraints()
+    {
+        return true;
+    }
+
+    /**
+     * Does this platform supports onUpdate in foreign key constraints?
+     *
+     * @return bool
+     */
+    public function supportsForeignKeyOnUpdate()
+    {
+        return ($this->supportsForeignKeyConstraints() && true);
+    }
+
+    /**
+     * Whether the platform supports database schemas.
+     *
+     * @return boolean
+     */
+    public function supportsSchemas()
+    {
+        return false;
+    }
+
+    /**
+     * Can this platform emulate schemas?
+     *
+     * Platforms that either support or emulate schemas don't automatically
+     * filter a schema for the namespaced elements in {@link
+     * AbstractManager#createSchema}.
+     *
+     * @return bool
+     */
+    public function canEmulateSchemas()
+    {
+        return false;
+    }
+
+    /**
+     * Some databases don't allow to create and drop databases at all or only with certain tools.
+     *
+     * @return bool
+     */
+    public function supportsCreateDropDatabase()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports getting the affected rows of a recent
+     * update/delete type query.
+     *
+     * @return boolean
+     */
+    public function supportsGettingAffectedRows()
+    {
+        return true;
+    }
+
+    /**
+     * Does this plaform support to add inline column comments as postfix.
+     *
+     * @return bool
+     */
+    public function supportsInlineColumnComments()
+    {
+        return false;
+    }
+
+    /**
+     * Does this platform support the propriortary synatx "COMMENT ON asset"
+     *
+     * @return bool
+     */
+    public function supportsCommentOnStatement()
+    {
+        return false;
+    }
+
+    public function getIdentityColumnNullInsertSQL()
+    {
+        return "";
+    }
+
+    /**
+     * Gets the format string, as accepted by the date() function, that describes
+     * the format of a stored datetime value of this platform.
+     *
+     * @return string The format string.
+     */
+    public function getDateTimeFormatString()
+    {
+        return 'Y-m-d H:i:s';
+    }
+
+    /**
+     * Gets the format string, as accepted by the date() function, that describes
+     * the format of a stored datetime with timezone value of this platform.
+     *
+     * @return string The format string.
+     */
+    public function getDateTimeTzFormatString()
+    {
+        return 'Y-m-d H:i:s';
+    }
+
+    /**
+     * Gets the format string, as accepted by the date() function, that describes
+     * the format of a stored date value of this platform.
+     *
+     * @return string The format string.
+     */
+    public function getDateFormatString()
+    {
+        return 'Y-m-d';
+    }
+
+    /**
+     * Gets the format string, as accepted by the date() function, that describes
+     * the format of a stored time value of this platform.
+     *
+     * @return string The format string.
+     */
+    public function getTimeFormatString()
+    {
+        return 'H:i:s';
+    }
+
+    /**
+     * Modify limit query
+     *
+     * @param string $query
+     * @param int $limit
+     * @param int $offset
+     * @return string
+     */
+    final public function modifyLimitQuery($query, $limit, $offset = null)
+    {
+        if ( $limit !== null) {
+            $limit = (int)$limit;
+        }
+
+        if ( $offset !== null) {
+            $offset = (int)$offset;
+
+            if ($offset < 0) {
+                throw new DBALException("LIMIT argument offset=$offset is not valid");
+            }
+            if ( $offset > 0 && ! $this->supportsLimitOffset()) {
+                throw new DBALException(sprintf("Platform %s does not support offset values in limit queries.", $this->getName()));
+            }
+        }
+
+        return $this->doModifyLimitQuery($query, $limit, $offset);
+    }
+
+    /**
+     * @param string $query
+     * @param int $limit
+     * @param int $offset
+     * @return string
+     */
+    protected function doModifyLimitQuery($query, $limit, $offset)
+    {
+        if ( $limit !== null) {
+            $query .= ' LIMIT ' . $limit;
+        }
+
+        if ( $offset !== null) {
+            $query .= ' OFFSET ' . $offset;
+        }
+
+        return $query;
+    }
+
+    /**
+     * Does the database platform support offsets in modify limit clauses?
+     *
+     * @return bool
+     */
+    public function supportsLimitOffset()
+    {
+        return true;
+    }
+
+    /**
+     * Gets the character casing of a column in an SQL result set of this platform.
+     *
+     * @param string $column The column name for which to get the correct character casing.
+     * @return string The column name in the character casing used in SQL result sets.
+     */
+    public function getSQLResultCasing($column)
+    {
+        return $column;
+    }
+
+    /**
+     * Makes any fixes to a name of a schema element (table, sequence, ...) that are required
+     * by restrictions of the platform, like a maximum length.
+     *
+     * @param string $schemaName
+     * @return string
+     */
+    public function fixSchemaElementName($schemaElementName)
+    {
+        return $schemaElementName;
+    }
+
+    /**
+     * Maximum length of any given databse identifier, like tables or column names.
+     *
+     * @return int
+     */
+    public function getMaxIdentifierLength()
+    {
+        return 63;
+    }
+
+    /**
+     * Get the insert sql for an empty insert statement
+     *
+     * @param string $tableName
+     * @param string $identifierColumnName
+     * @return string $sql
+     */
+    public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName)
+    {
+        return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)';
+    }
+
+    /**
+     * Generate a Truncate Table SQL statement for a given table.
+     *
+     * Cascade is not supported on many platforms but would optionally cascade the truncate by
+     * following the foreign keys.
+     *
+     * @param  string $tableName
+     * @param  bool $cascade
+     * @return string
+     */
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        return 'TRUNCATE '.$tableName;
+    }
+
+    /**
+     * This is for test reasons, many vendors have special requirements for dummy statements.
+     *
+     * @return string
+     */
+    public function getDummySelectSQL()
+    {
+        return 'SELECT 1';
+    }
+
+    /**
+     * Generate SQL to create a new savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function createSavePoint($savepoint)
+    {
+        return 'SAVEPOINT ' . $savepoint;
+    }
+
+    /**
+     * Generate SQL to release a savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function releaseSavePoint($savepoint)
+    {
+        return 'RELEASE SAVEPOINT ' . $savepoint;
+    }
+
+    /**
+     * Generate SQL to rollback a savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function rollbackSavePoint($savepoint)
+    {
+        return 'ROLLBACK TO SAVEPOINT ' . $savepoint;
+    }
+
+    /**
+     * Return the keyword list instance of this platform.
+     *
+     * Throws exception if no keyword list is specified.
+     *
+     * @throws DBALException
+     * @return KeywordList
+     */
+    final public function getReservedKeywordsList()
+    {
+        $class = $this->getReservedKeywordsClass();
+        $keywords = new $class;
+        if (!$keywords instanceof \Doctrine\DBAL\Platforms\Keywords\KeywordList) {
+            throw DBALException::notSupported(__METHOD__);
+        }
+        return $keywords;
+    }
+
+    /**
+     * The class name of the reserved keywords list.
+     *
+     * @return string
+     */
+    protected function getReservedKeywordsClass()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/DB2Platform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/DB2Platform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/DB2Platform.php	(revision 345)
@@ -0,0 +1,587 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\TableDiff;
+
+class DB2Platform extends AbstractPlatform
+{
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'smallint'      => 'smallint',
+            'bigint'        => 'bigint',
+            'integer'       => 'integer',
+            'time'          => 'time',
+            'date'          => 'date',
+            'varchar'       => 'string',
+            'character'     => 'string',
+            'clob'          => 'text',
+            'decimal'       => 'decimal',
+            'double'        => 'float',
+            'real'          => 'float',
+            'timestamp'     => 'datetime',
+        );
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a VARCHAR column type.
+     *
+     * @param array $field
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a CLOB column type.
+     *
+     * @param array $field
+     */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        // todo clob(n) with $field['length'];
+        return 'CLOB(1M)';
+    }
+
+    /**
+     * Gets the name of the platform.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'db2';
+    }
+
+
+    /**
+     * Gets the SQL snippet that declares a boolean column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    public function getBooleanTypeDeclarationSQL(array $columnDef)
+    {
+        return 'SMALLINT';
+    }
+
+    /**
+     * Gets the SQL snippet that declares a 4 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    public function getIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
+    }
+
+    /**
+     * Gets the SQL snippet that declares an 8 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    public function getBigIntTypeDeclarationSQL(array $columnDef)
+    {
+        return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
+    }
+
+    /**
+     * Gets the SQL snippet that declares a 2 byte integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    public function getSmallIntTypeDeclarationSQL(array $columnDef)
+    {
+        return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
+    }
+
+    /**
+     * Gets the SQL snippet that declares common properties of an integer column.
+     *
+     * @param array $columnDef
+     * @return string
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        $autoinc = '';
+        if ( ! empty($columnDef['autoincrement'])) {
+            $autoinc = ' GENERATED BY DEFAULT AS IDENTITY';
+        }
+        return $autoinc;
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create datetime fields in
+     * statements like CREATE TABLE
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
+            return "TIMESTAMP(0) WITH DEFAULT";
+        }
+
+        return 'TIMESTAMP(0)';
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create date fields in statements
+     * like CREATE TABLE.
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * Obtain DBMS specific SQL to be used to create time fields in statements
+     * like CREATE TABLE.
+     *
+     * @param array $fieldDeclaration
+     * @return string
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME';
+    }
+
+    public function getListDatabasesSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListSequencesSQL($database)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * This code fragment is originally from the Zend_Db_Adapter_Db2 class.
+     *
+     * @license New BSD License
+     * @param  string $table
+     * @return string
+     */
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
+                c.typename, c.default, c.nulls, c.length, c.scale,
+                c.identity, tc.type AS tabconsttype, k.colseq
+                FROM syscat.columns c
+                LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
+                ON (k.tabschema = tc.tabschema
+                    AND k.tabname = tc.tabname
+                    AND tc.type = 'P'))
+                ON (c.tabschema = k.tabschema
+                    AND c.tabname = k.tabname
+                    AND c.colname = k.colname)
+                WHERE UPPER(c.tabname) = UPPER('" . $table . "') ORDER BY c.colno";
+    }
+
+    public function getListTablesSQL()
+    {
+        return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'";
+    }
+
+    public function getListUsersSQL()
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    /**
+     * Get the SQL to list all views of a database or user.
+     *
+     * @param string $database
+     * @return string
+     */
+    public function getListViewsSQL($database)
+    {
+        return "SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS";
+    }
+
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        return "SELECT NAME, COLNAMES, UNIQUERULE FROM SYSIBM.SYSINDEXES WHERE TBNAME = UPPER('" . $table . "')";
+    }
+
+    public function getListTableForeignKeysSQL($table)
+    {
+        return "SELECT TBNAME, RELNAME, REFTBNAME, DELETERULE, UPDATERULE, FKCOLNAMES, PKCOLNAMES ".
+               "FROM SYSIBM.SYSRELS WHERE TBNAME = UPPER('".$table."')";
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return "CREATE VIEW ".$name." AS ".$sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return "DROP VIEW ".$name;
+    }
+
+    public function getDropSequenceSQL($sequence)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getSequenceNextValSQL($sequenceName)
+    {
+        throw DBALException::notSupported(__METHOD__);
+    }
+
+    public function getCreateDatabaseSQL($database)
+    {
+        return "CREATE DATABASE ".$database;
+    }
+
+    public function getDropDatabaseSQL($database)
+    {
+        return "DROP DATABASE ".$database.";";
+    }
+
+    public function supportsCreateDropDatabase()
+    {
+        return false;
+    }
+
+    /**
+     * Whether the platform supports releasing savepoints.
+     *
+     * @return boolean
+     */
+    public function supportsReleaseSavepoints()
+    {
+        return false;
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current date.
+     *
+     * @return string
+     */
+    public function getCurrentDateSQL()
+    {
+        return 'VALUES CURRENT DATE';
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current time.
+     *
+     * @return string
+     */
+    public function getCurrentTimeSQL()
+    {
+        return 'VALUES CURRENT TIME';
+    }
+
+    /**
+     * Gets the SQL specific for the platform to get the current timestamp
+     *
+     * @return string
+     */
+
+    public function getCurrentTimestampSQL()
+    {
+        return "VALUES CURRENT TIMESTAMP";
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set an index
+     * declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $name          name of the index
+     * @param Index $index          index definition
+     * @return string               DBMS specific SQL code portion needed to set an index
+     */
+    public function getIndexDeclarationSQL($name, Index $index)
+    {
+        return $this->getUniqueConstraintDeclarationSQL($name, $index);
+    }
+
+    /**
+     * @param string $tableName
+     * @param array $columns
+     * @param array $options
+     * @return array
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        $indexes = array();
+        if (isset($options['indexes'])) {
+            $indexes = $options['indexes'];
+        }
+        $options['indexes'] = array();
+
+        $sqls = parent::_getCreateTableSQL($tableName, $columns, $options);
+
+        foreach ($indexes as $index => $definition) {
+            $sqls[] = $this->getCreateIndexSQL($definition, $tableName);
+        }
+        return $sqls;
+    }
+
+    /**
+     * Gets the SQL to alter an existing table.
+     *
+     * @param TableDiff $diff
+     * @return array
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $sql = array();
+        $columnSql = array();
+
+        $queryParts = array();
+        foreach ($diff->addedColumns AS $fieldName => $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+        }
+
+        foreach ($diff->removedColumns AS $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] =  'DROP COLUMN ' . $column->getQuotedName($this);
+        }
+
+        foreach ($diff->changedColumns AS $columnDiff) {
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
+            $column = $columnDiff->column;
+            $queryParts[] =  'ALTER ' . ($columnDiff->oldColumnName) . ' '
+                    . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+        }
+
+        foreach ($diff->renamedColumns AS $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] =  'RENAME ' . $oldColumnName . ' TO ' . $column->getQuotedName($this);
+        }
+
+        $tableSql = array();
+
+        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
+            if (count($queryParts) > 0) {
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(" ", $queryParts);
+            }
+
+            $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
+
+            if ($diff->newName !== false) {
+                $sql[] =  'RENAME TABLE TO ' . $diff->newName;
+            }
+        }
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    public function getDefaultValueDeclarationSQL($field)
+    {
+        if (isset($field['notnull']) && $field['notnull'] && !isset($field['default'])) {
+            if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) {
+                $field['default'] = 0;
+            } else if((string)$field['type'] == "DateTime") {
+                $field['default'] = "00-00-00 00:00:00";
+            } else if ((string)$field['type'] == "Date") {
+                $field['default'] = "00-00-00";
+            } else if((string)$field['type'] == "Time") {
+                $field['default'] = "00:00:00";
+            } else {
+                $field['default'] = '';
+            }
+        }
+
+        unset($field['default']); // @todo this needs fixing
+        if (isset($field['version']) && $field['version']) {
+            if ((string)$field['type'] != "DateTime") {
+                $field['default'] = "1";
+            }
+        }
+
+        return parent::getDefaultValueDeclarationSQL($field);
+    }
+
+    /**
+     * Get the insert sql for an empty insert statement
+     *
+     * @param string $tableName
+     * @param string $identifierColumnName
+     * @return string $sql
+     */
+    public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName)
+    {
+        return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (DEFAULT)';
+    }
+
+    public function getCreateTemporaryTableSnippetSQL()
+    {
+        return "DECLARE GLOBAL TEMPORARY TABLE";
+    }
+
+    /**
+     * DB2 automatically moves temporary tables into the SESSION. schema.
+     *
+     * @param  string $tableName
+     * @return string
+     */
+    public function getTemporaryTableName($tableName)
+    {
+        return "SESSION." . $tableName;
+    }
+
+    protected function doModifyLimitQuery($query, $limit, $offset = null)
+    {
+        if ($limit === null && $offset === null) {
+            return $query;
+        }
+
+        $limit = (int)$limit;
+        $offset = (int)(($offset)?:0);
+
+        // Todo OVER() needs ORDER BY data!
+        $sql = 'SELECT db22.* FROM (SELECT ROW_NUMBER() OVER() AS DC_ROWNUM, db21.* '.
+               'FROM (' . $query . ') db21) db22 WHERE db22.DC_ROWNUM BETWEEN ' . ($offset+1) .' AND ' . ($offset+$limit);
+        return $sql;
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos == false) {
+            return 'LOCATE(' . $substr . ', ' . $str . ')';
+        } else {
+            return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
+        }
+    }
+
+    /**
+     * return string to call a function to get a substring inside an SQL statement
+     *
+     * Note: Not SQL92, but common functionality.
+     *
+     * SQLite only supports the 2 parameter variant of this function
+     *
+     * @param  string $value         an sql string literal or column name/alias
+     * @param  integer $from     where to start the substring portion
+     * @param  integer $len       the substring portion length
+     * @return string
+     */
+    public function getSubstringExpression($value, $from, $len = null)
+    {
+        if ($len === null)
+            return 'SUBSTR(' . $value . ', ' . $from . ')';
+        else {
+            return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')';
+        }
+    }
+
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    public function prefersIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * Gets the character casing of a column in an SQL result set of this platform.
+     *
+     * DB2 returns all column names in SQL result sets in uppercase.
+     *
+     * @param string $column The column name for which to get the correct character casing.
+     * @return string The column name in the character casing used in SQL result sets.
+     */
+    public function getSQLResultCasing($column)
+    {
+        return strtoupper($column);
+    }
+
+    public function getForUpdateSQL()
+    {
+        return ' WITH RR USE AND KEEP UPDATE LOCKS';
+    }
+
+    public function getDummySelectSQL()
+    {
+        return 'SELECT 1 FROM sysibm.sysdummy1';
+    }
+
+    /**
+     * DB2 supports savepoints, but they work semantically different than on other vendor platforms.
+     *
+     * TODO: We have to investigate how to get DB2 up and running with savepoints.
+     *
+     * @return bool
+     */
+    public function supportsSavepoints()
+    {
+        return false;
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php	(revision 345)
@@ -0,0 +1,438 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * DB2 Keywords
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DB2Keywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'DB2';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ACTIVATE',
+            'ADD',
+            'AFTER',
+            'ALIAS',
+            'ALL',
+            'ALLOCATE',
+            'DOCUMENT',
+            'DOUBLE',
+            'DROP',
+            'DSSIZE',
+            'DYNAMIC',
+            'EACH',
+            'LOCK',
+            'LOCKMAX',
+            'LOCKSIZE',
+            'LONG',
+            'LOOP',
+            'MAINTAINED',
+            'ROUND_CEILING',
+            'ROUND_DOWN',
+            'ROUND_FLOOR',
+            'ROUND_HALF_DOWN',
+            'ROUND_HALF_EVEN',
+            'ROUND_HALF_UP',
+            'ALLOW',
+            'ALTER',
+            'AND',
+            'ANY',
+            'AS',
+            'ASENSITIVE',
+            'ASSOCIATE',
+            'ASUTIME',
+            'AT',
+            'ATTRIBUTES',
+            'AUDIT',
+            'AUTHORIZATION',
+            'AUX',
+            'AUXILIARY',
+            'BEFORE',
+            'BEGIN',
+            'BETWEEN',
+            'BINARY',
+            'BUFFERPOOL',
+            'BY',
+            'CACHE',
+            'CALL',
+            'CALLED',
+            'CAPTURE',
+            'CARDINALITY',
+            'CASCADED',
+            'CASE',
+            'CAST',
+            'CCSID',
+            'CHAR',
+            'CHARACTER',
+            'CHECK',
+            'CLONE',
+            'CLOSE',
+            'CLUSTER',
+            'COLLECTION',
+            'COLLID',
+            'COLUMN',
+            'COMMENT',
+            'COMMIT',
+            'CONCAT',
+            'CONDITION',
+            'CONNECT',
+            'CONNECTION',
+            'CONSTRAINT',
+            'CONTAINS',
+            'CONTINUE',
+            'COUNT',
+            'COUNT_BIG',
+            'CREATE',
+            'CROSS',
+            'CURRENT',
+            'CURRENT_DATE',
+            'CURRENT_LC_CTYPE',
+            'CURRENT_PATH',
+            'CURRENT_SCHEMA',
+            'CURRENT_SERVER',
+            'CURRENT_TIME',
+            'CURRENT_TIMESTAMP',
+            'CURRENT_TIMEZONE',
+            'CURRENT_USER',
+            'CURSOR',
+            'CYCLE',
+            'DATA',
+            'DATABASE',
+            'DATAPARTITIONNAME',
+            'DATAPARTITIONNUM',
+            'EDITPROC',
+            'ELSE',
+            'ELSEIF',
+            'ENABLE',
+            'ENCODING',
+            'ENCRYPTION',
+            'END',
+            'END-EXEC',
+            'ENDING',
+            'ERASE',
+            'ESCAPE',
+            'EVERY',
+            'EXCEPT',
+            'EXCEPTION',
+            'EXCLUDING',
+            'EXCLUSIVE',
+            'EXECUTE',
+            'EXISTS',
+            'EXIT',
+            'EXPLAIN',
+            'EXTERNAL',
+            'EXTRACT',
+            'FENCED',
+            'FETCH',
+            'FIELDPROC',
+            'FILE',
+            'FINAL',
+            'FOR',
+            'FOREIGN',
+            'FREE',
+            'FROM',
+            'FULL',
+            'FUNCTION',
+            'GENERAL',
+            'GENERATED',
+            'GET',
+            'GLOBAL',
+            'GO',
+            'GOTO',
+            'GRANT',
+            'GRAPHIC',
+            'GROUP',
+            'HANDLER',
+            'HASH',
+            'HASHED_VALUE',
+            'HAVING',
+            'HINT',
+            'HOLD',
+            'HOUR',
+            'HOURS',
+            'IDENTITY',
+            'IF',
+            'IMMEDIATE',
+            'IN',
+            'INCLUDING',
+            'INCLUSIVE',
+            'INCREMENT',
+            'INDEX',
+            'INDICATOR',
+            'INF',
+            'INFINITY',
+            'INHERIT',
+            'INNER',
+            'INOUT',
+            'INSENSITIVE',
+            'INSERT',
+            'INTEGRITY',
+            'MATERIALIZED',
+            'MAXVALUE',
+            'MICROSECOND',
+            'MICROSECONDS',
+            'MINUTE',
+            'MINUTES',
+            'MINVALUE',
+            'MODE',
+            'MODIFIES',
+            'MONTH',
+            'MONTHS',
+            'NAN',
+            'NEW',
+            'NEW_TABLE',
+            'NEXTVAL',
+            'NO',
+            'NOCACHE',
+            'NOCYCLE',
+            'NODENAME',
+            'NODENUMBER',
+            'NOMAXVALUE',
+            'NOMINVALUE',
+            'NONE',
+            'NOORDER',
+            'NORMALIZED',
+            'NOT',
+            'NULL',
+            'NULLS',
+            'NUMPARTS',
+            'OBID',
+            'OF',
+            'OLD',
+            'OLD_TABLE',
+            'ON',
+            'OPEN',
+            'OPTIMIZATION',
+            'OPTIMIZE',
+            'OPTION',
+            'OR',
+            'ORDER',
+            'OUT',
+            'OUTER',
+            'OVER',
+            'OVERRIDING',
+            'PACKAGE',
+            'PADDED',
+            'PAGESIZE',
+            'PARAMETER',
+            'PART',
+            'PARTITION',
+            'PARTITIONED',
+            'PARTITIONING',
+            'PARTITIONS',
+            'PASSWORD',
+            'PATH',
+            'PIECESIZE',
+            'PLAN',
+            'POSITION',
+            'PRECISION',
+            'PREPARE',
+            'PREVVAL',
+            'PRIMARY',
+            'PRIQTY',
+            'PRIVILEGES',
+            'PROCEDURE',
+            'PROGRAM',
+            'PSID',
+            'ROUND_UP',
+            'ROUTINE',
+            'ROW',
+            'ROW_NUMBER',
+            'ROWNUMBER',
+            'ROWS',
+            'ROWSET',
+            'RRN',
+            'RUN',
+            'SAVEPOINT',
+            'SCHEMA',
+            'SCRATCHPAD',
+            'SCROLL',
+            'SEARCH',
+            'SECOND',
+            'SECONDS',
+            'SECQTY',
+            'SECURITY',
+            'SELECT',
+            'SENSITIVE',
+            'SEQUENCE',
+            'SESSION',
+            'SESSION_USER',
+            'SET',
+            'SIGNAL',
+            'SIMPLE',
+            'SNAN',
+            'SOME',
+            'SOURCE',
+            'SPECIFIC',
+            'SQL',
+            'SQLID',
+            'STACKED',
+            'STANDARD',
+            'START',
+            'STARTING',
+            'STATEMENT',
+            'STATIC',
+            'STATMENT',
+            'STAY',
+            'STOGROUP',
+            'STORES',
+            'STYLE',
+            'SUBSTRING',
+            'SUMMARY',
+            'SYNONYM',
+            'SYSFUN',
+            'SYSIBM',
+            'SYSPROC',
+            'SYSTEM',
+            'SYSTEM_USER',
+            'TABLE',
+            'TABLESPACE',
+            'THEN',
+            'TIME',
+            'TIMESTAMP',
+            'TO',
+            'TRANSACTION',
+            'TRIGGER',
+            'TRIM',
+            'TRUNCATE',
+            'TYPE',
+            'UNDO',
+            'UNION',
+            'UNIQUE',
+            'UNTIL',
+            'UPDATE',
+            'DATE',
+            'DAY',
+            'DAYS',
+            'DB2GENERAL',
+            'DB2GENRL',
+            'DB2SQL',
+            'DBINFO',
+            'DBPARTITIONNAME',
+            'DBPARTITIONNUM',
+            'DEALLOCATE',
+            'DECLARE',
+            'DEFAULT',
+            'DEFAULTS',
+            'DEFINITION',
+            'DELETE',
+            'DENSE_RANK',
+            'DENSERANK',
+            'DESCRIBE',
+            'DESCRIPTOR',
+            'DETERMINISTIC',
+            'DIAGNOSTICS',
+            'DISABLE',
+            'DISALLOW',
+            'DISCONNECT',
+            'DISTINCT',
+            'DO',
+            'INTERSECT',
+            'PUBLIC',
+            'USAGE',
+            'INTO',
+            'QUERY',
+            'USER',
+            'IS',
+            'QUERYNO',
+            'USING',
+            'ISOBID',
+            'RANGE',
+            'VALIDPROC',
+            'ISOLATION',
+            'RANK',
+            'VALUE',
+            'ITERATE',
+            'READ',
+            'VALUES',
+            'JAR',
+            'READS',
+            'VARIABLE',
+            'JAVA',
+            'RECOVERY',
+            'VARIANT',
+            'JOIN',
+            'REFERENCES',
+            'VCAT',
+            'KEEP',
+            'REFERENCING',
+            'VERSION',
+            'KEY',
+            'REFRESH',
+            'VIEW',
+            'LABEL',
+            'RELEASE',
+            'VOLATILE',
+            'LANGUAGE',
+            'RENAME',
+            'VOLUMES',
+            'LATERAL',
+            'REPEAT',
+            'WHEN',
+            'LC_CTYPE',
+            'RESET',
+            'WHENEVER',
+            'LEAVE',
+            'RESIGNAL',
+            'WHERE',
+            'LEFT',
+            'RESTART',
+            'WHILE',
+            'LIKE',
+            'RESTRICT',
+            'WITH',
+            'LINKTYPE',
+            'RESULT',
+            'WITHOUT',
+            'LOCAL',
+            'RESULT_SET_LOCATOR WLM',
+            'LOCALDATE',
+            'RETURN',
+            'WRITE',
+            'LOCALE',
+            'RETURNS',
+            'XMLELEMENT',
+            'LOCALTIME',
+            'REVOKE',
+            'XMLEXISTS',
+            'LOCALTIMESTAMP RIGHT',
+            'XMLNAMESPACES',
+            'LOCATOR',
+            'ROLE',
+            'YEAR',
+            'LOCATORS',
+            'ROLLBACK',
+            'YEARS',
+        );
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/KeywordList.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/KeywordList.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/KeywordList.php	(revision 345)
@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * Abstract interface for a SQL reserved keyword dictionary.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class KeywordList
+{
+    private $keywords = null;
+
+    /**
+     * Check if the given word is a keyword of this dialect/vendor platform.
+     *
+     * @param  string $word
+     * @return bool
+     */
+    public function isKeyword($word)
+    {
+        if ($this->keywords === null) {
+            $this->initializeKeywords();
+        }
+
+        return isset($this->keywords[strtoupper($word)]);
+    }
+
+    protected function initializeKeywords()
+    {
+        $this->keywords = array_flip(array_map('strtoupper', $this->getKeywords()));
+    }
+
+    abstract protected function getKeywords();
+
+    /**
+     * Name of this keyword list.
+     *
+     * @return string
+     */
+    abstract public function getName();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php	(revision 345)
@@ -0,0 +1,243 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * MsSQL Keywordlist
+ *
+ * @license  BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      David Coallier <davidc@php.net>
+ */
+class MsSQLKeywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'MsSQL';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ADD',
+            'CURRENT_TIMESTAMP',
+            'GROUP',
+            'OPENQUERY',
+            'SERIALIZABLE',
+            'ALL',
+            'CURRENT_USER',
+            'HAVING',
+            'OPENROWSET',
+            'SESSION_USER',
+            'ALTER',
+            'CURSOR',
+            'HOLDLOCK',
+            'OPTION',
+            'SET',
+            'AND',
+            'DATABASE',
+            'IDENTITY',
+            'OR',
+            'SETUSER',
+            'ANY',
+            'DBCC',
+            'IDENTITYCOL',
+            'ORDER',
+            'SHUTDOWN',
+            'AS',
+            'DEALLOCATE',
+            'IDENTITY_INSERT',
+            'OUTER',
+            'SOME',
+            'ASC',
+            'DECLARE',
+            'IF',
+            'OVER',
+            'STATISTICS',
+            'AUTHORIZATION',
+            'DEFAULT',
+            'IN',
+            'PERCENT',
+            'SUM',
+            'AVG',
+            'DELETE',
+            'INDEX',
+            'PERM',
+            'SYSTEM_USER',
+            'BACKUP',
+            'DENY',
+            'INNER',
+            'PERMANENT',
+            'TABLE',
+            'BEGIN',
+            'DESC',
+            'INSERT',
+            'PIPE',
+            'TAPE',
+            'BETWEEN',
+            'DISK',
+            'INTERSECT',
+            'PLAN',
+            'TEMP',
+            'BREAK',
+            'DISTINCT',
+            'INTO',
+            'PRECISION',
+            'TEMPORARY',
+            'BROWSE',
+            'DISTRIBUTED',
+            'IS',
+            'PREPARE',
+            'TEXTSIZE',
+            'BULK',
+            'DOUBLE',
+            'ISOLATION',
+            'PRIMARY',
+            'THEN',
+            'BY',
+            'DROP',
+            'JOIN',
+            'PRINT',
+            'TO',
+            'CASCADE',
+            'DUMMY',
+            'KEY',
+            'PRIVILEGES',
+            'TOP',
+            'CASE',
+            'DUMP',
+            'KILL',
+            'PROC',
+            'TRAN',
+            'CHECK',
+            'ELSE',
+            'LEFT',
+            'PROCEDURE',
+            'TRANSACTION',
+            'CHECKPOINT',
+            'END',
+            'LEVEL',
+            'PROCESSEXIT',
+            'TRIGGER',
+            'CLOSE',
+            'ERRLVL',
+            'LIKE',
+            'PUBLIC',
+            'TRUNCATE',
+            'CLUSTERED',
+            'ERROREXIT',
+            'LINENO',
+            'RAISERROR',
+            'TSEQUAL',
+            'COALESCE',
+            'ESCAPE',
+            'LOAD',
+            'READ',
+            'UNCOMMITTED',
+            'COLUMN',
+            'EXCEPT',
+            'MAX',
+            'READTEXT',
+            'UNION',
+            'COMMIT',
+            'EXEC',
+            'MIN',
+            'RECONFIGURE',
+            'UNIQUE',
+            'COMMITTED',
+            'EXECUTE',
+            'MIRROREXIT',
+            'REFERENCES',
+            'UPDATE',
+            'COMPUTE',
+            'EXISTS',
+            'NATIONAL',
+            'REPEATABLE',
+            'UPDATETEXT',
+            'CONFIRM',
+            'EXIT',
+            'NOCHECK',
+            'REPLICATION',
+            'USE',
+            'CONSTRAINT',
+            'FETCH',
+            'NONCLUSTERED',
+            'RESTORE',
+            'USER',
+            'CONTAINS',
+            'FILE',
+            'NOT',
+            'RESTRICT',
+            'VALUES',
+            'CONTAINSTABLE',
+            'FILLFACTOR',
+            'NULL',
+            'RETURN',
+            'VARYING',
+            'CONTINUE',
+            'FLOPPY',
+            'NULLIF',
+            'REVOKE',
+            'VIEW',
+            'CONTROLROW',
+            'FOR',
+            'OF',
+            'RIGHT',
+            'WAITFOR',
+            'CONVERT',
+            'FOREIGN',
+            'OFF',
+            'ROLLBACK',
+            'WHEN',
+            'COUNT',
+            'FREETEXT',
+            'OFFSETS',
+            'ROWCOUNT',
+            'WHERE',
+            'CREATE',
+            'FREETEXTTABLE',
+            'ON',
+            'ROWGUIDCOL',
+            'WHILE',
+            'CROSS',
+            'FROM',
+            'ONCE',
+            'RULE',
+            'WITH',
+            'CURRENT',
+            'FULL',
+            'ONLY',
+            'SAVE',
+            'WORK',
+            'CURRENT_DATE',
+            'GOTO',
+            'OPEN',
+            'SCHEMA',
+            'WRITETEXT',
+            'CURRENT_TIME',
+            'GRANT',
+            'OPENDATASOURCE',
+            'SELECT',
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php	(revision 345)
@@ -0,0 +1,268 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * MySQL Keywordlist
+ *
+ * @license  BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      David Coallier <davidc@php.net>
+ */
+class MySQLKeywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'MySQL';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ADD',
+            'ALL',
+            'ALTER',
+            'ANALYZE',
+            'AND',
+            'AS',
+            'ASC',
+            'ASENSITIVE',
+            'BEFORE',
+            'BETWEEN',
+            'BIGINT',
+            'BINARY',
+            'BLOB',
+            'BOTH',
+            'BY',
+            'CALL',
+            'CASCADE',
+            'CASE',
+            'CHANGE',
+            'CHAR',
+            'CHARACTER',
+            'CHECK',
+            'COLLATE',
+            'COLUMN',
+            'CONDITION',
+            'CONNECTION',
+            'CONSTRAINT',
+            'CONTINUE',
+            'CONVERT',
+            'CREATE',
+            'CROSS',
+            'CURRENT_DATE',
+            'CURRENT_TIME',
+            'CURRENT_TIMESTAMP',
+            'CURRENT_USER',
+            'CURSOR',
+            'DATABASE',
+            'DATABASES',
+            'DAY_HOUR',
+            'DAY_MICROSECOND',
+            'DAY_MINUTE',
+            'DAY_SECOND',
+            'DEC',
+            'DECIMAL',
+            'DECLARE',
+            'DEFAULT',
+            'DELAYED',
+            'DELETE',
+            'DESC',
+            'DESCRIBE',
+            'DETERMINISTIC',
+            'DISTINCT',
+            'DISTINCTROW',
+            'DIV',
+            'DOUBLE',
+            'DROP',
+            'DUAL',
+            'EACH',
+            'ELSE',
+            'ELSEIF',
+            'ENCLOSED',
+            'ESCAPED',
+            'EXISTS',
+            'EXIT',
+            'EXPLAIN',
+            'FALSE',
+            'FETCH',
+            'FLOAT',
+            'FLOAT4',
+            'FLOAT8',
+            'FOR',
+            'FORCE',
+            'FOREIGN',
+            'FROM',
+            'FULLTEXT',
+            'GOTO',
+            'GRANT',
+            'GROUP',
+            'HAVING',
+            'HIGH_PRIORITY',
+            'HOUR_MICROSECOND',
+            'HOUR_MINUTE',
+            'HOUR_SECOND',
+            'IF',
+            'IGNORE',
+            'IN',
+            'INDEX',
+            'INFILE',
+            'INNER',
+            'INOUT',
+            'INSENSITIVE',
+            'INSERT',
+            'INT',
+            'INT1',
+            'INT2',
+            'INT3',
+            'INT4',
+            'INT8',
+            'INTEGER',
+            'INTERVAL',
+            'INTO',
+            'IS',
+            'ITERATE',
+            'JOIN',
+            'KEY',
+            'KEYS',
+            'KILL',
+            'LABEL',
+            'LEADING',
+            'LEAVE',
+            'LEFT',
+            'LIKE',
+            'LIMIT',
+            'LINES',
+            'LOAD',
+            'LOCALTIME',
+            'LOCALTIMESTAMP',
+            'LOCK',
+            'LONG',
+            'LONGBLOB',
+            'LONGTEXT',
+            'LOOP',
+            'LOW_PRIORITY',
+            'MATCH',
+            'MEDIUMBLOB',
+            'MEDIUMINT',
+            'MEDIUMTEXT',
+            'MIDDLEINT',
+            'MINUTE_MICROSECOND',
+            'MINUTE_SECOND',
+            'MOD',
+            'MODIFIES',
+            'NATURAL',
+            'NOT',
+            'NO_WRITE_TO_BINLOG',
+            'NULL',
+            'NUMERIC',
+            'ON',
+            'OPTIMIZE',
+            'OPTION',
+            'OPTIONALLY',
+            'OR',
+            'ORDER',
+            'OUT',
+            'OUTER',
+            'OUTFILE',
+            'PRECISION',
+            'PRIMARY',
+            'PROCEDURE',
+            'PURGE',
+            'RAID0',
+            'READ',
+            'READS',
+            'REAL',
+            'REFERENCES',
+            'REGEXP',
+            'RELEASE',
+            'RENAME',
+            'REPEAT',
+            'REPLACE',
+            'REQUIRE',
+            'RESTRICT',
+            'RETURN',
+            'REVOKE',
+            'RIGHT',
+            'RLIKE',
+            'SCHEMA',
+            'SCHEMAS',
+            'SECOND_MICROSECOND',
+            'SELECT',
+            'SENSITIVE',
+            'SEPARATOR',
+            'SET',
+            'SHOW',
+            'SMALLINT',
+            'SONAME',
+            'SPATIAL',
+            'SPECIFIC',
+            'SQL',
+            'SQLEXCEPTION',
+            'SQLSTATE',
+            'SQLWARNING',
+            'SQL_BIG_RESULT',
+            'SQL_CALC_FOUND_ROWS',
+            'SQL_SMALL_RESULT',
+            'SSL',
+            'STARTING',
+            'STRAIGHT_JOIN',
+            'TABLE',
+            'TERMINATED',
+            'THEN',
+            'TINYBLOB',
+            'TINYINT',
+            'TINYTEXT',
+            'TO',
+            'TRAILING',
+            'TRIGGER',
+            'TRUE',
+            'UNDO',
+            'UNION',
+            'UNIQUE',
+            'UNLOCK',
+            'UNSIGNED',
+            'UPDATE',
+            'USAGE',
+            'USE',
+            'USING',
+            'UTC_DATE',
+            'UTC_TIME',
+            'UTC_TIMESTAMP',
+            'VALUES',
+            'VARBINARY',
+            'VARCHAR',
+            'VARCHARACTER',
+            'VARYING',
+            'WHEN',
+            'WHERE',
+            'WHILE',
+            'WITH',
+            'WRITE',
+            'X509',
+            'XOR',
+            'YEAR_MONTH',
+            'ZEROFILL',
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php	(revision 345)
@@ -0,0 +1,156 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * Oracle Keywordlist
+ *
+ * @license  BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      David Coallier <davidc@php.net>
+ */
+class OracleKeywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'Oracle';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ACCESS',
+            'ELSE',
+            'MODIFY',
+            'START',
+            'ADD',
+            'EXCLUSIVE',
+            'NOAUDIT',
+            'SELECT',
+            'ALL',
+            'EXISTS',
+            'NOCOMPRESS',
+            'SESSION',
+            'ALTER',
+            'FILE',
+            'NOT',
+            'SET',
+            'AND',
+            'FLOAT',
+            'NOTFOUND ',
+            'SHARE',
+            'ANY',
+            'FOR',
+            'NOWAIT',
+            'SIZE',
+            'ARRAYLEN',
+            'FROM',
+            'NULL',
+            'SMALLINT',
+            'AS',
+            'GRANT',
+            'NUMBER',
+            'SQLBUF',
+            'ASC',
+            'GROUP',
+            'OF',
+            'SUCCESSFUL',
+            'AUDIT',
+            'HAVING',
+            'OFFLINE ',
+            'SYNONYM',
+            'BETWEEN',
+            'IDENTIFIED',
+            'ON',
+            'SYSDATE',
+            'BY',
+            'IMMEDIATE',
+            'ONLINE',
+            'TABLE',
+            'CHAR',
+            'IN',
+            'OPTION',
+            'THEN',
+            'CHECK',
+            'INCREMENT',
+            'OR',
+            'TO',
+            'CLUSTER',
+            'INDEX',
+            'ORDER',
+            'TRIGGER',
+            'COLUMN',
+            'INITIAL',
+            'PCTFREE',
+            'UID',
+            'COMMENT',
+            'INSERT',
+            'PRIOR',
+            'UNION',
+            'COMPRESS',
+            'INTEGER',
+            'PRIVILEGES',
+            'UNIQUE',
+            'CONNECT',
+            'INTERSECT',
+            'PUBLIC',
+            'UPDATE',
+            'CREATE',
+            'INTO',
+            'RAW',
+            'USER',
+            'CURRENT',
+            'IS',
+            'RENAME',
+            'VALIDATE',
+            'DATE',
+            'LEVEL',
+            'RESOURCE',
+            'VALUES',
+            'DECIMAL',
+            'LIKE',
+            'REVOKE',
+            'VARCHAR',
+            'DEFAULT',
+            'LOCK',
+            'ROW',
+            'VARCHAR2',
+            'DELETE',
+            'LONG',
+            'ROWID',
+            'VIEW',
+            'DESC',
+            'MAXEXTENTS',
+            'ROWLABEL',
+            'WHENEVER',
+            'DISTINCT',
+            'MINUS',
+            'ROWNUM',
+            'WHERE',
+            'DROP',
+            'MODE',
+            'ROWS',
+            'WITH',
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php	(revision 345)
@@ -0,0 +1,131 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * PostgreSQL Keywordlist
+ *
+ * @license     BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Marcelo Santos Araujo <msaraujo@php.net>
+ */
+class PostgreSQLKeywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'PostgreSQL';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ALL',
+            'ANALYSE',
+            'ANALYZE',
+            'AND',
+            'ANY',
+            'AS',
+            'ASC',
+            'AUTHORIZATION',
+            'BETWEEN',
+            'BINARY',
+            'BOTH',
+            'CASE',
+            'CAST',
+            'CHECK',
+            'COLLATE',
+            'COLUMN',
+            'CONSTRAINT',
+            'CREATE',
+            'CURRENT_DATE',
+            'CURRENT_TIME',
+            'CURRENT_TIMESTAMP',
+            'CURRENT_USER',
+            'DEFAULT',
+            'DEFERRABLE',
+            'DESC',
+            'DISTINCT',
+            'DO',
+            'ELSE',
+            'END',
+            'EXCEPT',
+            'FALSE',
+            'FOR',
+            'FOREIGN',
+            'FREEZE',
+            'FROM',
+            'FULL',
+            'GRANT',
+            'GROUP',
+            'HAVING',
+            'ILIKE',
+            'IN',
+            'INITIALLY',
+            'INNER',
+            'INTERSECT',
+            'INTO',
+            'IS',
+            'ISNULL',
+            'JOIN',
+            'LEADING',
+            'LEFT',
+            'LIKE',
+            'LIMIT',
+            'LOCALTIME',
+            'LOCALTIMESTAMP',
+            'NATURAL',
+            'NEW',
+            'NOT',
+            'NOTNULL',
+            'NULL',
+            'OFF',
+            'OFFSET',
+            'OLD',
+            'ON',
+            'ONLY',
+            'OR',
+            'ORDER',
+            'OUTER',
+            'OVERLAPS',
+            'PLACING',
+            'PRIMARY',
+            'REFERENCES',
+            'SELECT',
+            'SESSION_USER',
+            'SIMILAR',
+            'SOME',
+            'TABLE',
+            'THEN',
+            'TO',
+            'TRAILING',
+            'TRUE',
+            'UNION',
+            'UNIQUE',
+            'USER',
+            'USING',
+            'VERBOSE',
+            'WHEN',
+            'WHERE'
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php	(revision 345)
@@ -0,0 +1,116 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+use Doctrine\DBAL\Schema\Table;
+use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Schema\ForeignKeyConstraint;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Schema\Sequence;
+use Doctrine\DBAL\Schema\Index;
+
+class ReservedKeywordsValidator implements Visitor
+{
+    /**
+     * @var KeywordList[]
+     */
+    private $keywordLists = array();
+
+    /**
+     * @var array
+     */
+    private $violations = array();
+
+    public function __construct(array $keywordLists)
+    {
+        $this->keywordLists = $keywordLists;
+    }
+
+    public function getViolations()
+    {
+        return $this->violations;
+    }
+
+    /**
+     * @param string $word
+     * @return array
+     */
+    private function isReservedWord($word)
+    {
+        if ($word[0] == "`") {
+            $word = str_replace('`', '', $word);
+        }
+
+        $keywordLists = array();
+        foreach ($this->keywordLists AS $keywordList) {
+            if ($keywordList->isKeyword($word)) {
+                $keywordLists[] = $keywordList->getName();
+            }
+        }
+        return $keywordLists;
+    }
+
+    private function addViolation($asset, $violatedPlatforms)
+    {
+        if (!$violatedPlatforms) {
+            return;
+        }
+
+        $this->violations[] = $asset . ' keyword violations: ' . implode(', ', $violatedPlatforms);
+    }
+
+    public function acceptColumn(Table $table, Column $column)
+    {
+        $this->addViolation(
+            'Table ' . $table->getName() . ' column ' . $column->getName(),
+            $this->isReservedWord($column->getName())
+        );
+    }
+
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
+    {
+
+    }
+
+    public function acceptIndex(Table $table, Index $index)
+    {
+
+    }
+
+    public function acceptSchema(Schema $schema)
+    {
+
+    }
+
+    public function acceptSequence(Sequence $sequence)
+    {
+
+    }
+
+    public function acceptTable(Table $table)
+    {
+        $this->addViolation(
+            'Table ' . $table->getName(),
+            $this->isReservedWord($table->getName())
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php	(revision 345)
@@ -0,0 +1,164 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * SQLite Keywords
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SQLiteKeywords extends KeywordList
+{
+    public function getName()
+    {
+        return 'SQLite';
+    }
+
+    protected function getKeywords()
+    {
+        return array(
+            'ABORT',
+            'ACTION',
+            'ADD',
+            'AFTER',
+            'ALL',
+            'ALTER',
+            'ANALYZE',
+            'AND',
+            'AS',
+            'ASC',
+            'ATTACH',
+            'AUTOINCREMENT',
+            'BEFORE',
+            'BEGIN',
+            'BETWEEN',
+            'BY',
+            'CASCADE',
+            'CASE',
+            'CAST',
+            'CHECK',
+            'COLLATE',
+            'COLUMN',
+            'COMMIT',
+            'CONFLICT',
+            'CONSTRAINT',
+            'CREATE',
+            'CROSS',
+            'CURRENT_DATE',
+            'CURRENT_TIME',
+            'CURRENT_TIMESTAMP',
+            'DATABASE',
+            'DEFAULT',
+            'DEFERRABLE',
+            'DEFERRED',
+            'DELETE',
+            'DESC',
+            'DETACH',
+            'DISTINCT',
+            'DROP',
+            'EACH',
+            'ELSE',
+            'END',
+            'ESCAPE',
+            'EXCEPT',
+            'EXCLUSIVE',
+            'EXISTS',
+            'EXPLAIN',
+            'FAIL',
+            'FOR',
+            'FOREIGN',
+            'FROM',
+            'FULL',
+            'GLOB',
+            'GROUP',
+            'HAVING',
+            'IF',
+            'IGNORE',
+            'IMMEDIATE',
+            'IN',
+            'INDEX',
+            'INDEXED',
+            'INITIALLY',
+            'INNER',
+            'INSERT',
+            'INSTEAD',
+            'INTERSECT',
+            'INTO',
+            'IS',
+            'ISNULL',
+            'JOIN',
+            'KEY',
+            'LEFT',
+            'LIKE',
+            'LIMIT',
+            'MATCH',
+            'NATURAL',
+            'NO',
+            'NOT',
+            'NOTNULL',
+            'NULL',
+            'OF',
+            'OFFSET',
+            'ON',
+            'OR',
+            'ORDER',
+            'OUTER',
+            'PLAN',
+            'PRAGMA',
+            'PRIMARY',
+            'QUERY',
+            'RAISE',
+            'REFERENCES',
+            'REGEXP',
+            'REINDEX',
+            'RELEASE',
+            'RENAME',
+            'REPLACE',
+            'RESTRICT',
+            'RIGHT',
+            'ROLLBACK',
+            'ROW',
+            'SAVEPOINT',
+            'SELECT',
+            'SET',
+            'TABLE',
+            'TEMP',
+            'TEMPORARY',
+            'THEN',
+            'TO',
+            'TRANSACTION',
+            'TRIGGER',
+            'UNION',
+            'UNIQUE',
+            'UPDATE',
+            'USING',
+            'VACUUM',
+            'VALUES',
+            'VIEW',
+            'VIRTUAL',
+            'WHEN',
+            'WHERE'
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/MySqlPlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/MySqlPlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/MySqlPlatform.php	(revision 345)
@@ -0,0 +1,768 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\DBALException,
+    Doctrine\DBAL\Schema\TableDiff,
+    Doctrine\DBAL\Schema\Index,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * The MySqlPlatform provides the behavior, features and SQL dialect of the
+ * MySQL database platform. This platform represents a MySQL 5.0 or greater platform that
+ * uses the InnoDB storage engine.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Rename: MySQLPlatform
+ */
+class MySqlPlatform extends AbstractPlatform
+{
+    /**
+     * Gets the character used for identifier quoting.
+     *
+     * @return string
+     * @override
+     */
+    public function getIdentifierQuoteCharacter()
+    {
+        return '`';
+    }
+
+    /**
+     * Returns the regular expression operator.
+     *
+     * @return string
+     * @override
+     */
+    public function getRegexpExpression()
+    {
+        return 'RLIKE';
+    }
+
+    /**
+     * Returns global unique identifier
+     *
+     * @return string to get global unique identifier
+     * @override
+     */
+    public function getGuidExpression()
+    {
+        return 'UUID()';
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos == false) {
+            return 'LOCATE(' . $substr . ', ' . $str . ')';
+        } else {
+            return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
+        }
+    }
+
+    /**
+     * Returns a series of strings concatinated
+     *
+     * concat() accepts an arbitrary number of parameters. Each parameter
+     * must contain an expression or an array with expressions.
+     *
+     * @param string|array(string) strings that will be concatinated.
+     * @override
+     */
+    public function getConcatExpression()
+    {
+        $args = func_get_args();
+        return 'CONCAT(' . join(', ', (array) $args) . ')';
+    }
+
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')';
+    }
+
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return 'DATE_ADD(' . $date . ', INTERVAL ' . $days . ' DAY)';
+    }
+
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return 'DATE_SUB(' . $date . ', INTERVAL ' . $days . ' DAY)';
+    }
+
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return 'DATE_ADD(' . $date . ', INTERVAL ' . $months . ' MONTH)';
+    }
+
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return 'DATE_SUB(' . $date . ', INTERVAL ' . $months . ' MONTH)';
+    }
+
+    public function getListDatabasesSQL()
+    {
+        return 'SHOW DATABASES';
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        return 'SHOW INDEX FROM ' . $table;
+    }
+
+    /**
+     * Two approaches to listing the table indexes. The information_schema is
+     * prefered, because it doesn't cause problems with SQL keywords such as "order" or "table".
+     *
+     * @param string $table
+     * @param string $currentDatabase
+     * @return string
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        if ($currentDatabase) {
+            return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ".
+                   "SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ".
+                   "CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " .
+                   "NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " .
+                   "FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'";
+        } else {
+            return 'SHOW INDEX FROM ' . $table;
+        }
+    }
+
+    public function getListViewsSQL($database)
+    {
+        return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'";
+    }
+
+    public function getListTableForeignKeysSQL($table, $database = null)
+    {
+        $sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ".
+               "k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ".
+               "FROM information_schema.key_column_usage k /*!50116 ".
+               "INNER JOIN information_schema.referential_constraints c ON ".
+               "  c.constraint_name = k.constraint_name AND ".
+               "  c.table_name = '$table' */ WHERE k.table_name = '$table'";
+
+        if ($database) {
+            $sql .= " AND k.table_schema = '$database' /*!50116 AND c.constraint_schema = '$database' */";
+        }
+
+        $sql .= " AND k.`REFERENCED_COLUMN_NAME` is not NULL";
+
+        return $sql;
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW '. $name;
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
+     *
+     * @params array $field
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+    }
+
+    /** @override */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        if ( ! empty($field['length']) && is_numeric($field['length'])) {
+            $length = $field['length'];
+            if ($length <= 255) {
+                return 'TINYTEXT';
+            } else if ($length <= 65532) {
+                return 'TEXT';
+            } else if ($length <= 16777215) {
+                return 'MEDIUMTEXT';
+            }
+        }
+        return 'LONGTEXT';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
+            return 'TIMESTAMP';
+        } else {
+            return 'DATETIME';
+        }
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME';
+    }
+
+    /**
+     * @override
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'TINYINT(1)';
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to set the COLLATION
+     * of a field declaration to be used in statements like CREATE TABLE.
+     *
+     * @param string $collation   name of the collation
+     * @return string  DBMS specific SQL code portion needed to set the COLLATION
+     *                 of a field declaration.
+     */
+    public function getCollationFieldDeclaration($collation)
+    {
+        return 'COLLATE ' . $collation;
+    }
+
+    /**
+     * Whether the platform prefers identity columns for ID generation.
+     * MySql prefers "autoincrement" identity columns since sequences can only
+     * be emulated with a table.
+     *
+     * @return boolean
+     * @override
+     */
+    public function prefersIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports identity columns.
+     * MySql supports this through AUTO_INCREMENT columns.
+     *
+     * @return boolean
+     * @override
+     */
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    public function supportsInlineColumnComments()
+    {
+        return true;
+    }
+
+    public function getShowDatabasesSQL()
+    {
+        return 'SHOW DATABASES';
+    }
+
+    public function getListTablesSQL()
+    {
+        return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
+    }
+
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        if ($database) {
+            return "SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ".
+                   "COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, " .
+                   "CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS CollactionName ".
+                   "FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" . $database . "' AND TABLE_NAME = '" . $table . "'";
+        } else {
+            return 'DESCRIBE ' . $table;
+        }
+    }
+
+    /**
+     * create a new database
+     *
+     * @param string $name name of the database that should be created
+     * @return string
+     * @override
+     */
+    public function getCreateDatabaseSQL($name)
+    {
+        return 'CREATE DATABASE ' . $name;
+    }
+
+    /**
+     * drop an existing database
+     *
+     * @param string $name name of the database that should be dropped
+     * @return string
+     * @override
+     */
+    public function getDropDatabaseSQL($name)
+    {
+        return 'DROP DATABASE ' . $name;
+    }
+
+    /**
+     * create a new table
+     *
+     * @param string $tableName   Name of the database that should be created
+     * @param array $columns  Associative array that contains the definition of each field of the new table
+     *                       The indexes of the array entries are the names of the fields of the table an
+     *                       the array entry values are associative arrays like those that are meant to be
+     *                       passed with the field definitions to get[Type]Declaration() functions.
+     *                          array(
+     *                              'id' => array(
+     *                                  'type' => 'integer',
+     *                                  'unsigned' => 1
+     *                                  'notnull' => 1
+     *                                  'default' => 0
+     *                              ),
+     *                              'name' => array(
+     *                                  'type' => 'text',
+     *                                  'length' => 12
+     *                              ),
+     *                              'password' => array(
+     *                                  'type' => 'text',
+     *                                  'length' => 12
+     *                              )
+     *                          );
+     * @param array $options  An associative array of table options:
+     *                          array(
+     *                              'comment' => 'Foo',
+     *                              'charset' => 'utf8',
+     *                              'collate' => 'utf8_unicode_ci',
+     *                              'engine' => 'innodb',
+     *                              'foreignKeys' => array(
+     *                                  new ForeignKeyConstraint(),
+     *                                  new ForeignKeyConstraint(),
+     *                                  new ForeignKeyConstraint(),
+     *                                  // etc
+     *                              )
+     *                          );
+     *
+     * @return void
+     * @override
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+            foreach ($options['uniqueConstraints'] as $index => $definition) {
+                $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition);
+            }
+        }
+
+        // add all indexes
+        if (isset($options['indexes']) && ! empty($options['indexes'])) {
+            foreach($options['indexes'] as $index => $definition) {
+                $queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
+            }
+        }
+
+        // attach all primary keys
+        if (isset($options['primary']) && ! empty($options['primary'])) {
+            $keyColumns = array_unique(array_values($options['primary']));
+            $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
+        }
+
+        $query = 'CREATE ';
+        if (!empty($options['temporary'])) {
+            $query .= 'TEMPORARY ';
+        }
+        $query.= 'TABLE ' . $tableName . ' (' . $queryFields . ')';
+
+        $optionStrings = array();
+
+        if (isset($options['comment'])) {
+            $optionStrings['comment'] = 'COMMENT = ' . $options['comment'];
+        }
+        if (isset($options['charset'])) {
+            $optionStrings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset'];
+            if (isset($options['collate'])) {
+                $optionStrings['charset'] .= ' COLLATE ' . $options['collate'];
+            }
+        }
+
+        // get the type of the table
+        if (isset($options['engine'])) {
+            $optionStrings[] = 'ENGINE = ' . $options['engine'];
+        } else {
+            // default to innodb
+            $optionStrings[] = 'ENGINE = InnoDB';
+        }
+
+        if ( ! empty($optionStrings)) {
+            $query.= ' '.implode(' ', $optionStrings);
+        }
+        $sql[] = $query;
+
+        if (isset($options['foreignKeys'])) {
+            foreach ((array) $options['foreignKeys'] as $definition) {
+                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Gets the SQL to alter an existing table.
+     *
+     * @param TableDiff $diff
+     * @return array
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $columnSql = array();
+        $queryParts = array();
+        if ($diff->newName !== false) {
+            $queryParts[] =  'RENAME TO ' . $diff->newName;
+        }
+
+        foreach ($diff->addedColumns AS $fieldName => $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $columnArray = $column->toArray();
+            $columnArray['comment'] = $this->getColumnComment($column);
+            $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+        }
+
+        foreach ($diff->removedColumns AS $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] =  'DROP ' . $column->getQuotedName($this);
+        }
+
+        foreach ($diff->changedColumns AS $columnDiff) {
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
+            $column = $columnDiff->column;
+            $columnArray = $column->toArray();
+            $columnArray['comment'] = $this->getColumnComment($column);
+            $queryParts[] =  'CHANGE ' . ($columnDiff->oldColumnName) . ' '
+                    . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+        }
+
+        foreach ($diff->renamedColumns AS $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $columnArray = $column->toArray();
+            $columnArray['comment'] = $this->getColumnComment($column);
+            $queryParts[] =  'CHANGE ' . $oldColumnName . ' '
+                    . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+        }
+
+        $sql = array();
+        $tableSql = array();
+
+        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
+            if (count($queryParts) > 0) {
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(", ", $queryParts);
+            }
+            $sql = array_merge(
+                $this->getPreAlterTableIndexForeignKeySQL($diff),
+                $sql,
+                $this->getPostAlterTableIndexForeignKeySQL($diff)
+            );
+        }
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    /**
+     * Fix for DROP/CREATE index after foreign key change from OneToOne to ManyToOne
+     *
+     * @param TableDiff $diff
+     * @return array
+     */
+    protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
+    {
+        $sql = array();
+        $table = $diff->name;
+
+        foreach ($diff->removedIndexes AS $remKey => $remIndex) {
+
+            foreach ($diff->addedIndexes as $addKey => $addIndex) {
+                if ($remIndex->getColumns() == $addIndex->getColumns()) {
+
+                    $columns = $addIndex->getColumns();
+                    $type = '';
+                    if ($addIndex->isUnique()) {
+                        $type = 'UNIQUE ';
+                    }
+
+                    $query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', ';
+                    $query .= 'ADD ' . $type . 'INDEX ' . $addIndex->getName();
+                    $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')';
+
+                    $sql[] = $query;
+
+                    unset($diff->removedIndexes[$remKey]);
+                    unset($diff->addedIndexes[$addKey]);
+
+                    break;
+                }
+            }
+        }
+
+        $sql = array_merge($sql, parent::getPreAlterTableIndexForeignKeySQL($diff));
+
+        return $sql;
+    }
+
+    /**
+     * Obtain DBMS specific SQL code portion needed to declare an integer type
+     * field to be used in statements like CREATE TABLE.
+     *
+     * @param string  $name   name the field to be declared.
+     * @param string  $field  associative array with the name of the properties
+     *                        of the field being declared as array indexes.
+     *                        Currently, the types of supported field
+     *                        properties are as follows:
+     *
+     *                       unsigned
+     *                        Boolean flag that indicates whether the field
+     *                        should be declared as unsigned integer if
+     *                        possible.
+     *
+     *                       default
+     *                        Integer value to be used as default for this
+     *                        field.
+     *
+     *                       notnull
+     *                        Boolean flag that indicates whether this field is
+     *                        constrained to not be set to null.
+     * @return string  DBMS specific SQL code portion that should be used to
+     *                 declare the specified field.
+     * @override
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /** @override */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /** @override */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /** @override */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        $autoinc = '';
+        if ( ! empty($columnDef['autoincrement'])) {
+            $autoinc = ' AUTO_INCREMENT';
+        }
+        $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
+
+        return $unsigned . $autoinc;
+    }
+
+    /**
+     * Return the FOREIGN KEY query section dealing with non-standard options
+     * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
+     *
+     * @param ForeignKeyConstraint $foreignKey
+     * @return string
+     * @override
+     */
+    public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
+    {
+        $query = '';
+        if ($foreignKey->hasOption('match')) {
+            $query .= ' MATCH ' . $foreignKey->getOption('match');
+        }
+        $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
+        return $query;
+    }
+
+    /**
+     * Gets the SQL to drop an index of a table.
+     *
+     * @param Index $index           name of the index to be dropped
+     * @param string|Table $table          name of table that should be used in method
+     * @override
+     */
+    public function getDropIndexSQL($index, $table=null)
+    {
+        if($index instanceof Index) {
+            $indexName = $index->getQuotedName($this);
+        } else if(is_string($index)) {
+            $indexName = $index;
+        } else {
+            throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
+        }
+
+        if($table instanceof Table) {
+            $table = $table->getQuotedName($this);
+        } else if(!is_string($table)) {
+            throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
+        }
+
+        if ($index instanceof Index && $index->isPrimary()) {
+            // mysql primary keys are always named "PRIMARY",
+            // so we cannot use them in statements because of them being keyword.
+            return $this->getDropPrimaryKeySQL($table);
+        }
+
+        return 'DROP INDEX ' . $indexName . ' ON ' . $table;
+    }
+
+    /**
+     * @param Index $index
+     * @param Table $table
+     */
+    protected function getDropPrimaryKeySQL($table)
+    {
+        return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
+    }
+
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    /**
+     * Get the platform name for this instance.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'mysql';
+    }
+
+    public function getReadLockSQL()
+    {
+        return 'LOCK IN SHARE MODE';
+    }
+
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'tinyint'       => 'boolean',
+            'smallint'      => 'smallint',
+            'mediumint'     => 'integer',
+            'int'           => 'integer',
+            'integer'       => 'integer',
+            'bigint'        => 'bigint',
+            'tinytext'      => 'text',
+            'mediumtext'    => 'text',
+            'longtext'      => 'text',
+            'text'          => 'text',
+            'varchar'       => 'string',
+            'string'        => 'string',
+            'char'          => 'string',
+            'date'          => 'date',
+            'datetime'      => 'datetime',
+            'timestamp'     => 'datetime',
+            'time'          => 'time',
+            'float'         => 'float',
+            'double'        => 'float',
+            'real'          => 'float',
+            'decimal'       => 'decimal',
+            'numeric'       => 'decimal',
+            'year'          => 'date',
+            'longblob'      => 'blob',
+            'blob'          => 'blob',
+            'mediumblob'    => 'blob',
+            'tinyblob'      => 'blob',
+        );
+    }
+
+    public function getVarcharMaxLength()
+    {
+        return 65535;
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords';
+    }
+
+    /**
+     * Get SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction.
+     *
+     * MySQL commits a transaction implicitly when DROP TABLE is executed, however not
+     * if DROP TEMPORARY TABLE is executed.
+     *
+     * @throws \InvalidArgumentException
+     * @param $table
+     * @return string
+     */
+    public function getDropTemporaryTableSQL($table)
+    {
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        } else if(!is_string($table)) {
+            throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
+        }
+
+        return 'DROP TEMPORARY TABLE ' . $table;
+    }
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'LONGBLOB';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/OraclePlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/OraclePlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/OraclePlatform.php	(revision 345)
@@ -0,0 +1,840 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Schema\TableDiff;
+
+/**
+ * OraclePlatform.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OraclePlatform extends AbstractPlatform
+{
+    /**
+     * return string to call a function to get a substring inside an SQL statement
+     *
+     * Note: Not SQL92, but common functionality.
+     *
+     * @param string $value         an sql string literal or column name/alias
+     * @param integer $position     where to start the substring portion
+     * @param integer $length       the substring portion length
+     * @return string               SQL substring function with given parameters
+     * @override
+     */
+    public function getSubstringExpression($value, $position, $length = null)
+    {
+        if ($length !== null) {
+            return "SUBSTR($value, $position, $length)";
+        }
+
+        return "SUBSTR($value, $position)";
+    }
+
+    /**
+     * Return string to call a variable with the current timestamp inside an SQL statement
+     * There are three special variables for current date and time:
+     * - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
+     * - CURRENT_DATE (date, DATE type)
+     * - CURRENT_TIME (time, TIME type)
+     *
+     * @return string to call a variable with the current timestamp
+     * @override
+     */
+    public function getNowExpression($type = 'timestamp')
+    {
+        switch ($type) {
+            case 'date':
+            case 'time':
+            case 'timestamp':
+            default:
+                return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')';
+        }
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos == false) {
+            return 'INSTR('.$str.', '.$substr.')';
+        } else {
+            return 'INSTR('.$str.', '.$substr.', '.$startPos.')';
+        }
+    }
+
+    /**
+     * Returns global unique identifier
+     *
+     * @return string to get global unique identifier
+     * @override
+     */
+    public function getGuidExpression()
+    {
+        return 'SYS_GUID()';
+    }
+
+    /**
+     * Get the number of days difference between two dates.
+     *
+     * Note: Since Oracle timestamp differences are calculated down to the microsecond we have to truncate
+     * them to the difference in days. This is obviously a restriction of the original functionality, but we
+     * need to make this a portable function.
+     *
+     * @param type $date1
+     * @param type $date2
+     * @return type
+     */
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return "TRUNC(TO_NUMBER(SUBSTR((" . $date1 . "-" . $date2 . "), 1, INSTR(" . $date1 . "-" . $date2 .", ' '))))";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return '(' . $date . '+' . $days . ')';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return '(' . $date . '-' . $days . ')';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return "ADD_MONTHS(" . $date . ", " . $months . ")";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return "ADD_MONTHS(" . $date . ", -" . $months . ")";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBitAndComparisonExpression($value1, $value2)
+    {
+        return 'BITAND('.$value1 . ', ' . $value2 . ')';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBitOrComparisonExpression($value1, $value2)
+    {
+        return '(' . $value1 . '-' .
+                $this->getBitAndComparisonExpression($value1, $value2)
+                . '+' . $value2 . ')';
+    }
+
+    /**
+     * Gets the SQL used to create a sequence that starts with a given value
+     * and increments by the given allocation size.
+     *
+     * Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH.
+     * Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection
+     * in {@see listSequences()}
+     *
+     * @param \Doctrine\DBAL\Schema\Sequence $sequence
+     * @return string
+     */
+    public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' START WITH ' . $sequence->getInitialValue() .
+               ' MINVALUE ' . $sequence->getInitialValue() .
+               ' INCREMENT BY ' . $sequence->getAllocationSize();
+    }
+
+    public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' INCREMENT BY ' . $sequence->getAllocationSize();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param string $sequenceName
+     * @override
+     */
+    public function getSequenceNextValSQL($sequenceName)
+    {
+        return 'SELECT ' . $sequenceName . '.nextval FROM DUAL';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param integer $level
+     * @override
+     */
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    protected function _getTransactionIsolationLevelSQL($level)
+    {
+        switch ($level) {
+            case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED:
+                return 'READ UNCOMMITTED';
+            case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED:
+                return 'READ COMMITTED';
+            case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ:
+            case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE:
+                return 'SERIALIZABLE';
+            default:
+                return parent::_getTransactionIsolationLevelSQL($level);
+        }
+    }
+
+    /**
+     * @override
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'NUMBER(1)';
+    }
+
+    /**
+     * @override
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        return 'NUMBER(10)';
+    }
+
+    /**
+     * @override
+     */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        return 'NUMBER(20)';
+    }
+
+    /**
+     * @override
+     */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return 'NUMBER(5)';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0)';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0) WITH TIME ZONE';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        return '';
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a VARCHAR column on the Oracle platform.
+     *
+     * @params array $field
+     * @override
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)')
+                : ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)');
+    }
+
+    /** @override */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'CLOB';
+    }
+
+    public function getListDatabasesSQL()
+    {
+        return 'SELECT username FROM all_users';
+    }
+
+    public function getListSequencesSQL($database)
+    {
+        return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ".
+               "WHERE SEQUENCE_OWNER = '".strtoupper($database)."'";
+    }
+
+    /**
+     *
+     * @param string $table
+     * @param array $columns
+     * @param array $options
+     * @return array
+     */
+    protected function _getCreateTableSQL($table, array $columns, array $options = array())
+    {
+        $indexes = isset($options['indexes']) ? $options['indexes'] : array();
+        $options['indexes'] = array();
+        $sql = parent::_getCreateTableSQL($table, $columns, $options);
+
+        foreach ($columns as $name => $column) {
+            if (isset($column['sequence'])) {
+                $sql[] = $this->getCreateSequenceSQL($column['sequence'], 1);
+            }
+
+            if (isset($column['autoincrement']) && $column['autoincrement'] ||
+               (isset($column['autoinc']) && $column['autoinc'])) {
+                $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table));
+            }
+        }
+
+        if (isset($indexes) && ! empty($indexes)) {
+            foreach ($indexes as $indexName => $index) {
+                $sql[] = $this->getCreateIndexSQL($index, $table);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html
+     * @param  string $table
+     * @return string
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        $table = strtoupper($table);
+
+        return "SELECT uind.index_name AS name, " .
+             "       uind.index_type AS type, " .
+             "       decode( uind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1 ) AS is_unique, " .
+             "       uind_col.column_name AS column_name, " .
+             "       uind_col.column_position AS column_pos, " .
+             "       (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ".
+             "FROM user_indexes uind, user_ind_columns uind_col " .
+             "WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '$table' ORDER BY uind_col.column_position ASC";
+    }
+
+    public function getListTablesSQL()
+    {
+        return 'SELECT * FROM sys.user_tables';
+    }
+
+    public function getListViewsSQL($database)
+    {
+        return 'SELECT view_name, text FROM sys.user_views';
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW '. $name;
+    }
+
+    public function getCreateAutoincrementSql($name, $table, $start = 1)
+    {
+        $table = strtoupper($table);
+        $sql   = array();
+
+        $indexName  = $table . '_AI_PK';
+        $definition = array(
+            'primary' => true,
+            'columns' => array($name => true),
+        );
+
+        $idx = new \Doctrine\DBAL\Schema\Index($indexName, array($name), true, true);
+
+        $sql[] = 'DECLARE
+  constraints_Count NUMBER;
+BEGIN
+  SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\';
+  IF constraints_Count = 0 OR constraints_Count = \'\' THEN
+    EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $table).'\';
+  END IF;
+END;';
+
+        $sequenceName = $table . '_SEQ';
+        $sequence = new \Doctrine\DBAL\Schema\Sequence($sequenceName, $start);
+        $sql[] = $this->getCreateSequenceSQL($sequence);
+
+        $triggerName  = $table . '_AI_PK';
+        $sql[] = 'CREATE TRIGGER ' . $triggerName . '
+   BEFORE INSERT
+   ON ' . $table . '
+   FOR EACH ROW
+DECLARE
+   last_Sequence NUMBER;
+   last_InsertID NUMBER;
+BEGIN
+   SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
+   IF (:NEW.' . $name . ' IS NULL OR :NEW.'.$name.' = 0) THEN
+      SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
+   ELSE
+      SELECT NVL(Last_Number, 0) INTO last_Sequence
+        FROM User_Sequences
+       WHERE Sequence_Name = \'' . $sequenceName . '\';
+      SELECT :NEW.' . $name . ' INTO last_InsertID FROM DUAL;
+      WHILE (last_InsertID > last_Sequence) LOOP
+         SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
+      END LOOP;
+   END IF;
+END;';
+        return $sql;
+    }
+
+    public function getDropAutoincrementSql($table)
+    {
+        $table = strtoupper($table);
+        $trigger = $table . '_AI_PK';
+
+        if ($trigger) {
+            $sql[] = 'DROP TRIGGER ' . $trigger;
+            $sql[] = $this->getDropSequenceSQL($table.'_SEQ');
+
+            $indexName = $table . '_AI_PK';
+            $sql[] = $this->getDropConstraintSQL($indexName, $table);
+        }
+
+        return $sql;
+    }
+
+    public function getListTableForeignKeysSQL($table)
+    {
+        $table = strtoupper($table);
+
+        return "SELECT alc.constraint_name,
+          alc.DELETE_RULE,
+          alc.search_condition,
+          cols.column_name \"local_column\",
+          cols.position,
+          r_alc.table_name \"references_table\",
+          r_cols.column_name \"foreign_column\"
+     FROM user_cons_columns cols
+LEFT JOIN user_constraints alc
+       ON alc.constraint_name = cols.constraint_name
+LEFT JOIN user_constraints r_alc
+       ON alc.r_constraint_name = r_alc.constraint_name
+LEFT JOIN user_cons_columns r_cols
+       ON r_alc.constraint_name = r_cols.constraint_name
+      AND cols.position = r_cols.position
+    WHERE alc.constraint_name = cols.constraint_name
+      AND alc.constraint_type = 'R'
+      AND alc.table_name = '".$table."'";
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        $table = strtoupper($table);
+        return 'SELECT * FROM user_constraints WHERE table_name = \'' . $table . '\'';
+    }
+
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        $table = strtoupper($table);
+
+        $tabColumnsTableName = "user_tab_columns";
+        $ownerCondition = '';
+        if(null !== $database){
+            $database = strtoupper($database);
+            $tabColumnsTableName = "all_tab_columns";
+            $ownerCondition = "AND c.owner = '".$database."'";
+        }
+
+        return "SELECT c.*, d.comments FROM $tabColumnsTableName c ".
+               "INNER JOIN user_col_comments d ON d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ".
+               "WHERE c.table_name = '" . $table . "' ".$ownerCondition." ORDER BY c.column_name";
+    }
+
+    /**
+     *
+     * @param  \Doctrine\DBAL\Schema\Sequence $sequence
+     * @return string
+     */
+    public function getDropSequenceSQL($sequence)
+    {
+        if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
+            $sequence = $sequence->getQuotedName($this);
+        }
+
+        return 'DROP SEQUENCE ' . $sequence;
+    }
+
+    /**
+     * @param  ForeignKeyConstraint|string $foreignKey
+     * @param  Table|string $table
+     * @return string
+     */
+    public function getDropForeignKeySQL($foreignKey, $table)
+    {
+        if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
+            $foreignKey = $foreignKey->getQuotedName($this);
+        }
+
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
+    }
+
+    public function getDropDatabaseSQL($database)
+    {
+        return 'DROP USER ' . $database . ' CASCADE';
+    }
+
+    /**
+     * Gets the sql statements for altering an existing table.
+     *
+     * The method returns an array of sql statements, since some platforms need several statements.
+     *
+     * @param string $diff->name          name of the table that is intended to be changed.
+     * @param array $changes        associative array that contains the details of each type      *
+     * @param boolean $check        indicates whether the function should just check if the DBMS driver
+     *                              can perform the requested table alterations if the value is true or
+     *                              actually perform them otherwise.
+     * @return array
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $sql = array();
+        $commentsSQL = array();
+        $columnSql = array();
+
+        $fields = array();
+        foreach ($diff->addedColumns AS $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+            if ($comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+        if (count($fields)) {
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ADD (' . implode(', ', $fields) . ')';
+        }
+
+        $fields = array();
+        foreach ($diff->changedColumns AS $columnDiff) {
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            $column = $columnDiff->column;
+            $fields[] = $column->getQuotedName($this). ' ' . $this->getColumnDeclarationSQL('', $column->toArray());
+            if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+        if (count($fields)) {
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' MODIFY (' . implode(', ', $fields) . ')';
+        }
+
+        foreach ($diff->renamedColumns AS $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName .' TO ' . $column->getQuotedName($this);
+        }
+
+        $fields = array();
+        foreach ($diff->removedColumns AS $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $fields[] = $column->getQuotedName($this);
+        }
+        if (count($fields)) {
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' DROP (' . implode(', ', $fields).')';
+        }
+
+        $tableSql = array();
+
+        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
+            if ($diff->newName !== false) {
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
+            }
+
+            $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
+        }
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    /**
+     * Whether the platform prefers sequences for ID generation.
+     *
+     * @return boolean
+     */
+    public function prefersSequences()
+    {
+        return true;
+    }
+
+    public function supportsCommentOnStatement()
+    {
+        return true;
+    }
+
+    /**
+     * Get the platform name for this instance
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'oracle';
+    }
+
+    /**
+     * Adds an driver-specific LIMIT clause to the query
+     *
+     * @param string $query         query to modify
+     * @param integer $limit        limit the number of rows
+     * @param integer $offset       start reading from given offset
+     * @return string               the modified query
+     */
+    protected function doModifyLimitQuery($query, $limit, $offset = null)
+    {
+        $limit = (int) $limit;
+        $offset = (int) $offset;
+        if (preg_match('/^\s*SELECT/i', $query)) {
+            if (!preg_match('/\sFROM\s/i', $query)) {
+                $query .= " FROM dual";
+            }
+            if ($limit > 0) {
+                $max = $offset + $limit;
+                $column = '*';
+                if ($offset > 0) {
+                    $min = $offset + 1;
+                    $query = 'SELECT * FROM (SELECT a.' . $column . ', rownum AS doctrine_rownum FROM (' .
+                            $query .
+                            ') a WHERE rownum <= ' . $max . ') WHERE doctrine_rownum >= ' . $min;
+                } else {
+                    $query = 'SELECT a.' . $column . ' FROM (' . $query . ') a WHERE ROWNUM <= ' . $max;
+                }
+            }
+        }
+        return $query;
+    }
+
+    /**
+     * Gets the character casing of a column in an SQL result set of this platform.
+     *
+     * Oracle returns all column names in SQL result sets in uppercase.
+     *
+     * @param string $column The column name for which to get the correct character casing.
+     * @return string The column name in the character casing used in SQL result sets.
+     */
+    public function getSQLResultCasing($column)
+    {
+        return strtoupper($column);
+    }
+
+    public function getCreateTemporaryTableSnippetSQL()
+    {
+        return "CREATE GLOBAL TEMPORARY TABLE";
+    }
+
+    public function getDateTimeTzFormatString()
+    {
+        return 'Y-m-d H:i:sP';
+    }
+
+    public function getDateFormatString()
+    {
+        return 'Y-m-d 00:00:00';
+    }
+
+    public function getTimeFormatString()
+    {
+        return '1900-01-01 H:i:s';
+    }
+
+    public function fixSchemaElementName($schemaElementName)
+    {
+        if (strlen($schemaElementName) > 30) {
+            // Trim it
+            return substr($schemaElementName, 0, 30);
+        }
+        return $schemaElementName;
+    }
+
+    /**
+     * Maximum length of any given databse identifier, like tables or column names.
+     *
+     * @return int
+     */
+    public function getMaxIdentifierLength()
+    {
+        return 30;
+    }
+
+    /**
+     * Whether the platform supports sequences.
+     *
+     * @return boolean
+     */
+    public function supportsSequences()
+    {
+        return true;
+    }
+
+    public function supportsForeignKeyOnUpdate()
+    {
+        return false;
+    }
+
+    /**
+     * Whether the platform supports releasing savepoints.
+     *
+     * @return boolean
+     */
+    public function supportsReleaseSavepoints()
+    {
+        return false;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        return 'TRUNCATE TABLE '.$tableName;
+    }
+
+    /**
+     * This is for test reasons, many vendors have special requirements for dummy statements.
+     *
+     * @return string
+     */
+    public function getDummySelectSQL()
+    {
+        return 'SELECT 1 FROM DUAL';
+    }
+
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'integer'           => 'integer',
+            'number'            => 'integer',
+            'pls_integer'       => 'boolean',
+            'binary_integer'    => 'boolean',
+            'varchar'           => 'string',
+            'varchar2'          => 'string',
+            'nvarchar2'         => 'string',
+            'char'              => 'string',
+            'nchar'             => 'string',
+            'date'              => 'datetime',
+            'timestamp'         => 'datetime',
+            'timestamptz'       => 'datetimetz',
+            'float'             => 'float',
+            'long'              => 'string',
+            'clob'              => 'text',
+            'nclob'             => 'text',
+            'raw'               => 'text',
+            'long raw'          => 'text',
+            'rowid'             => 'string',
+            'urowid'            => 'string',
+            'blob'              => 'blob',
+        );
+    }
+
+    /**
+     * Generate SQL to release a savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function releaseSavePoint($savepoint)
+    {
+        return '';
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords';
+    }
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'BLOB';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php	(revision 345)
@@ -0,0 +1,792 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Schema\TableDiff,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * PostgreSqlPlatform.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Rename: PostgreSQLPlatform
+ */
+class PostgreSqlPlatform extends AbstractPlatform
+{
+    /**
+     * Returns part of a string.
+     *
+     * Note: Not SQL92, but common functionality.
+     *
+     * @param string $value the target $value the string or the string column.
+     * @param int $from extract from this characeter.
+     * @param int $len extract this amount of characters.
+     * @return string sql that extracts part of a string.
+     * @override
+     */
+    public function getSubstringExpression($value, $from, $len = null)
+    {
+        if ($len === null) {
+            return 'SUBSTR(' . $value . ', ' . $from . ')';
+        } else {
+            return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')';
+        }
+    }
+
+    /**
+     * Returns the SQL string to return the current system date and time.
+     *
+     * @return string
+     */
+    public function getNowExpression()
+    {
+        return 'LOCALTIMESTAMP(0)';
+    }
+
+    /**
+     * regexp
+     *
+     * @return string           the regular expression operator
+     * @override
+     */
+    public function getRegexpExpression()
+    {
+        return 'SIMILAR TO';
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos !== false) {
+            $str = $this->getSubstringExpression($str, $startPos);
+            return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END';
+        } else {
+            return 'POSITION('.$substr.' IN '.$str.')';
+        }
+    }
+
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))';
+    }
+
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return "(" . $date ." + (" . $days . " || ' day')::interval)";
+    }
+
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return "(" . $date ." - (" . $days . " || ' day')::interval)";
+    }
+
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return "(" . $date ." + (" . $months . " || ' month')::interval)";
+    }
+
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return "(" . $date ." - (" . $months . " || ' month')::interval)";
+    }
+
+    /**
+     * parses a literal boolean value and returns
+     * proper sql equivalent
+     *
+     * @param string $value     boolean value to be parsed
+     * @return string           parsed boolean value
+     */
+    /*public function parseBoolean($value)
+    {
+        return $value;
+    }*/
+
+    /**
+     * Whether the platform supports sequences.
+     * Postgres has native support for sequences.
+     *
+     * @return boolean
+     */
+    public function supportsSequences()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports database schemas.
+     *
+     * @return boolean
+     */
+    public function supportsSchemas()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports identity columns.
+     * Postgres supports these through the SERIAL keyword.
+     *
+     * @return boolean
+     */
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    public function supportsCommentOnStatement()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform prefers sequences for ID generation.
+     *
+     * @return boolean
+     */
+    public function prefersSequences()
+    {
+        return true;
+    }
+
+    public function getListDatabasesSQL()
+    {
+        return 'SELECT datname FROM pg_database';
+    }
+
+    public function getListSequencesSQL($database)
+    {
+        return "SELECT
+                    c.relname, n.nspname AS schemaname
+                FROM
+                   pg_class c, pg_namespace n
+                WHERE relkind = 'S' AND n.oid = c.relnamespace AND
+                    (n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')";
+    }
+
+    public function getListTablesSQL()
+    {
+        return "SELECT tablename AS table_name, schemaname AS schema_name
+                FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' AND schemaname != 'information_schema' AND tablename != 'geometry_columns' AND tablename != 'spatial_ref_sys'";
+    }
+
+    public function getListViewsSQL($database)
+    {
+        return 'SELECT viewname, definition FROM pg_views';
+    }
+
+    public function getListTableForeignKeysSQL($table, $database = null)
+    {
+        return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
+                  FROM pg_catalog.pg_constraint r
+                  WHERE r.conrelid =
+                  (
+                      SELECT c.oid
+                      FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
+                      WHERE " .$this->getTableWhereClause($table) ." AND n.oid = c.relnamespace
+                  )
+                  AND r.contype = 'f'";
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW '. $name;
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        return "SELECT
+                    relname
+                FROM
+                    pg_class
+                WHERE oid IN (
+                    SELECT indexrelid
+                    FROM pg_index, pg_class
+                    WHERE pg_class.relname = '$table'
+                        AND pg_class.oid = pg_index.indrelid
+                        AND (indisunique = 't' OR indisprimary = 't')
+                        )";
+    }
+
+    /**
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+     * @param  string $table
+     * @return string
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        return "SELECT relname, pg_index.indisunique, pg_index.indisprimary,
+                       pg_index.indkey, pg_index.indrelid
+                 FROM pg_class, pg_index
+                 WHERE oid IN (
+                    SELECT indexrelid
+                    FROM pg_index si, pg_class sc, pg_namespace sn
+                    WHERE " . $this->getTableWhereClause($table, 'sc', 'sn')." AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
+                 ) AND pg_index.indexrelid = oid";
+    }
+
+    /**
+     * @param string $table
+     * @param string $classAlias
+     * @param string $namespaceAlias
+     * @return string
+     */
+    private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n')
+    {
+        $whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
+        if (strpos($table, ".") !== false) {
+            list($schema, $table) = explode(".", $table);
+            $schema = "'" . $schema . "'";
+        } else {
+            $schema = "ANY(string_to_array((select setting from pg_catalog.pg_settings where name = 'search_path'),','))";
+        }
+        $whereClause .= "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = $schema";
+
+        return $whereClause;
+    }
+
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        return "SELECT
+                    a.attnum,
+                    a.attname AS field,
+                    t.typname AS type,
+                    format_type(a.atttypid, a.atttypmod) AS complete_type,
+                    (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
+                    (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2
+                     WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type,
+                    a.attnotnull AS isnotnull,
+                    (SELECT 't'
+                     FROM pg_index
+                     WHERE c.oid = pg_index.indrelid
+                        AND pg_index.indkey[0] = a.attnum
+                        AND pg_index.indisprimary = 't'
+                    ) AS pri,
+                    (SELECT pg_attrdef.adsrc
+                     FROM pg_attrdef
+                     WHERE c.oid = pg_attrdef.adrelid
+                        AND pg_attrdef.adnum=a.attnum
+                    ) AS default,
+                    (SELECT pg_description.description
+                        FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid
+                    ) AS comment
+                    FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n
+                    WHERE ".$this->getTableWhereClause($table, 'c', 'n') ."
+                        AND a.attnum > 0
+                        AND a.attrelid = c.oid
+                        AND a.atttypid = t.oid
+                        AND n.oid = c.relnamespace
+                    ORDER BY a.attnum";
+    }
+
+    /**
+     * create a new database
+     *
+     * @param string $name name of the database that should be created
+     * @throws PDOException
+     * @return void
+     * @override
+     */
+    public function getCreateDatabaseSQL($name)
+    {
+        return 'CREATE DATABASE ' . $name;
+    }
+
+    /**
+     * drop an existing database
+     *
+     * @param string $name name of the database that should be dropped
+     * @throws PDOException
+     * @access public
+     */
+    public function getDropDatabaseSQL($name)
+    {
+        return 'DROP DATABASE ' . $name;
+    }
+
+    /**
+     * Return the FOREIGN KEY query section dealing with non-standard options
+     * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
+     *
+     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey         foreign key definition
+     * @return string
+     * @override
+     */
+    public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
+    {
+        $query = '';
+        if ($foreignKey->hasOption('match')) {
+            $query .= ' MATCH ' . $foreignKey->getOption('match');
+        }
+        $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
+        if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
+            $query .= ' DEFERRABLE';
+        } else {
+            $query .= ' NOT DEFERRABLE';
+        }
+        if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) {
+            $query .= ' INITIALLY DEFERRED';
+        } else {
+            $query .= ' INITIALLY IMMEDIATE';
+        }
+        return $query;
+    }
+
+    /**
+     * generates the sql for altering an existing table on postgresql
+     *
+     * @param string $name          name of the table that is intended to be changed.
+     * @param array $changes        associative array that contains the details of each type      *
+     * @param boolean $check        indicates whether the function should just check if the DBMS driver
+     *                              can perform the requested table alterations if the value is true or
+     *                              actually perform them otherwise.
+     * @see Doctrine_Export::alterTable()
+     * @return array
+     * @override
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $sql = array();
+        $commentsSQL = array();
+        $columnSql = array();
+
+        foreach ($diff->addedColumns as $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            if ($comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+
+        foreach ($diff->removedColumns as $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $query = 'DROP ' . $column->getQuotedName($this);
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+        }
+
+        foreach ($diff->changedColumns AS $columnDiff) {
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            $oldColumnName = $columnDiff->oldColumnName;
+            $column = $columnDiff->column;
+
+            if ($columnDiff->hasChanged('type')) {
+                $type = $column->getType();
+
+                // here was a server version check before, but DBAL API does not support this anymore.
+                $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this);
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+            if ($columnDiff->hasChanged('default')) {
+                $query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray());
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+            if ($columnDiff->hasChanged('notnull')) {
+                $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL';
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+            if ($columnDiff->hasChanged('autoincrement')) {
+                if ($column->getAutoincrement()) {
+                    // add autoincrement
+                    $seqName = $diff->name . '_' . $oldColumnName . '_seq';
+
+                    $sql[] = "CREATE SEQUENCE " . $seqName;
+                    $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->name . "))";
+                    $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
+                    $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
+                } else {
+                    // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
+                    $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT";
+                    $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
+                }
+            }
+            if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+
+        foreach ($diff->renamedColumns as $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getQuotedName($this);
+        }
+
+        $tableSql = array();
+
+        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
+            if ($diff->newName !== false) {
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
+            }
+
+            $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
+        }
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    /**
+     * Gets the SQL to create a sequence on this platform.
+     *
+     * @param \Doctrine\DBAL\Schema\Sequence $sequence
+     * @return string
+     */
+    public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' INCREMENT BY ' . $sequence->getAllocationSize() .
+               ' MINVALUE ' . $sequence->getInitialValue() .
+               ' START ' . $sequence->getInitialValue();
+    }
+
+    public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' INCREMENT BY ' . $sequence->getAllocationSize();
+    }
+
+    /**
+     * Drop existing sequence
+     * @param  \Doctrine\DBAL\Schema\Sequence $sequence
+     * @return string
+     */
+    public function getDropSequenceSQL($sequence)
+    {
+        if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
+            $sequence = $sequence->getQuotedName($this);
+        }
+        return 'DROP SEQUENCE ' . $sequence;
+    }
+
+    /**
+     * @param  ForeignKeyConstraint|string $foreignKey
+     * @param  Table|string $table
+     * @return string
+     */
+    public function getDropForeignKeySQL($foreignKey, $table)
+    {
+        return $this->getDropConstraintSQL($foreignKey, $table);
+    }
+
+    /**
+     * Gets the SQL used to create a table.
+     *
+     * @param unknown_type $tableName
+     * @param array $columns
+     * @param array $options
+     * @return unknown
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['primary']) && ! empty($options['primary'])) {
+            $keyColumns = array_unique(array_values($options['primary']));
+            $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
+        }
+
+        $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')';
+
+        $sql[] = $query;
+
+        if (isset($options['indexes']) && ! empty($options['indexes'])) {
+            foreach ($options['indexes'] AS $index) {
+                $sql[] = $this->getCreateIndexSQL($index, $tableName);
+            }
+        }
+
+        if (isset($options['foreignKeys'])) {
+            foreach ((array) $options['foreignKeys'] as $definition) {
+                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Postgres wants boolean values converted to the strings 'true'/'false'.
+     *
+     * @param array $item
+     * @override
+     */
+    public function convertBooleans($item)
+    {
+        if (is_array($item)) {
+            foreach ($item as $key => $value) {
+                if (is_bool($value) || is_numeric($item)) {
+                    $item[$key] = ($value) ? 'true' : 'false';
+                }
+            }
+        } else {
+           if (is_bool($item) || is_numeric($item)) {
+               $item = ($item) ? 'true' : 'false';
+           }
+        }
+        return $item;
+    }
+
+    public function getSequenceNextValSQL($sequenceName)
+    {
+        return "SELECT NEXTVAL('" . $sequenceName . "')";
+    }
+
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
+                . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    /**
+     * @override
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'BOOLEAN';
+    }
+
+    /**
+     * @override
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        if ( ! empty($field['autoincrement'])) {
+            return 'SERIAL';
+        }
+
+        return 'INT';
+    }
+
+    /**
+     * @override
+     */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        if ( ! empty($field['autoincrement'])) {
+            return 'BIGSERIAL';
+        }
+        return 'BIGINT';
+    }
+
+    /**
+     * @override
+     */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return 'SMALLINT';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0) WITHOUT TIME ZONE';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0) WITH TIME ZONE';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME(0) WITHOUT TIME ZONE';
+    }
+
+    /**
+     * @override
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        return '';
+    }
+
+    /**
+     * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
+     *
+     * @params array $field
+     * @override
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+    }
+
+    /** @override */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'TEXT';
+    }
+
+    /**
+     * Get the platform name for this instance
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'postgresql';
+    }
+
+    /**
+     * Gets the character casing of a column in an SQL result set.
+     *
+     * PostgreSQL returns all column names in SQL result sets in lowercase.
+     *
+     * @param string $column The column name for which to get the correct character casing.
+     * @return string The column name in the character casing used in SQL result sets.
+     */
+    public function getSQLResultCasing($column)
+    {
+        return strtolower($column);
+    }
+
+    public function getDateTimeTzFormatString()
+    {
+        return 'Y-m-d H:i:sO';
+    }
+
+    /**
+     * Get the insert sql for an empty insert statement
+     *
+     * @param string $tableName
+     * @param string $identifierColumnName
+     * @return string $sql
+     */
+    public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
+    {
+        return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        return 'TRUNCATE '.$tableName.' '.(($cascade)?'CASCADE':'');
+    }
+
+    public function getReadLockSQL()
+    {
+        return 'FOR SHARE';
+    }
+
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'smallint'      => 'smallint',
+            'int2'          => 'smallint',
+            'serial'        => 'integer',
+            'serial4'       => 'integer',
+            'int'           => 'integer',
+            'int4'          => 'integer',
+            'integer'       => 'integer',
+            'bigserial'     => 'bigint',
+            'serial8'       => 'bigint',
+            'bigint'        => 'bigint',
+            'int8'          => 'bigint',
+            'bool'          => 'boolean',
+            'boolean'       => 'boolean',
+            'text'          => 'text',
+            'varchar'       => 'string',
+            'interval'      => 'string',
+            '_varchar'      => 'string',
+            'char'          => 'string',
+            'bpchar'        => 'string',
+            'date'          => 'date',
+            'datetime'      => 'datetime',
+            'timestamp'     => 'datetime',
+            'timestamptz'   => 'datetimetz',
+            'time'          => 'time',
+            'timetz'        => 'time',
+            'float'         => 'float',
+            'float4'        => 'float',
+            'float8'        => 'float',
+            'double'        => 'float',
+            'double precision' => 'float',
+            'real'          => 'float',
+            'decimal'       => 'decimal',
+            'money'         => 'decimal',
+            'numeric'       => 'decimal',
+            'year'          => 'date',
+            'bytea'         => 'blob',
+        );
+    }
+
+    public function getVarcharMaxLength()
+    {
+        return 65535;
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords';
+    }
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'BYTEA';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2005Platform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2005Platform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2005Platform.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+/**
+ * Platform to ensure compatibility of Doctrine with SQLServer2005 version and
+ * higher.
+ *
+ * Differences to SQL Server 2008 are:
+ *
+ * - DATETIME2 datatype does not exist, only DATETIME which has a precision of
+ *   3. This is not supported by PHP DateTime, so we are emulating it by
+ *   setting .000 manually.
+ * - Starting with SQLServer2005 VARCHAR(MAX), VARBINARY(MAX) and
+ *   NVARCHAR(max) replace the old TEXT, NTEXT and IMAGE types. See
+ *   {@link http://www.sql-server-helper.com/faq/sql-server-2005-varchar-max-p01.aspx}
+ *   for more information.
+ */
+class SQLServer2005Platform extends SQLServerPlatform
+{
+    /**
+     * @override
+     */
+    public function supportsLimitOffset()
+    {
+        return true;
+    }
+	
+    /** @override */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'VARCHAR(MAX)';
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2008Platform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2008Platform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServer2008Platform.php	(revision 345)
@@ -0,0 +1,90 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+/**
+ * Platform to ensure compatibility of Doctrine with SQLServer2008 version.
+ *
+ * Differences to SQL Server 2005 and before are that a new DATETIME2 type was
+ * introduced that has a higher precision.
+ */
+class SQLServer2008Platform extends SQLServer2005Platform
+{
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        // 3 - microseconds precision length
+        // http://msdn.microsoft.com/en-us/library/ms187819.aspx
+        return 'DATETIME2(6)';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME(0)';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeFormatString()
+    {
+        return 'Y-m-d H:i:s.u';
+    }
+
+    /**
+     * @override
+	 */
+    public function getDateFormatString()
+    {
+        return 'Y-m-d';
+    }
+
+    /**
+     * @override
+	 */
+    public function getTimeFormatString()
+    {
+        return 'H:i:s';
+    }
+
+    /**
+     * Adding Datetime2 Type
+     */
+    protected function initializeDoctrineTypeMappings()
+    {
+        parent::initializeDoctrineTypeMappings();
+        $this->doctrineTypeMapping['datetime2'] = 'datetime';
+        $this->doctrineTypeMapping['date'] = 'date';
+        $this->doctrineTypeMapping['time'] = 'time';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServerPlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServerPlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServerPlatform.php	(revision 345)
@@ -0,0 +1,865 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Schema\Index,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * The SQLServerPlatform provides the behavior, features and SQL dialect of the
+ * Microsoft SQL Server database platform.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SQLServerPlatform extends AbstractPlatform
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')';
+    }
+
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return 'DATEADD(day, ' . $days . ', ' . $date . ')';
+    }
+
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return 'DATEADD(day, -1 * ' . $days . ', ' . $date . ')';
+    }
+
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return 'DATEADD(month, ' . $months . ', ' . $date . ')';
+    }
+
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return 'DATEADD(month, -1 * ' . $months . ', ' . $date . ')';
+    }
+
+    /**
+     * Whether the platform prefers identity columns for ID generation.
+     * MsSql prefers "autoincrement" identity columns since sequences can only
+     * be emulated with a table.
+     *
+     * @return boolean
+     * @override
+     */
+    public function prefersIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports identity columns.
+     * MsSql supports this through AUTO_INCREMENT columns.
+     *
+     * @return boolean
+     * @override
+     */
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * Whether the platform supports releasing savepoints.
+     *
+     * @return boolean
+     */
+    public function supportsReleaseSavepoints()
+    {
+        return false;
+    }
+
+    /**
+     * create a new database
+     *
+     * @param string $name name of the database that should be created
+     * @return string
+     * @override
+     */
+    public function getCreateDatabaseSQL($name)
+    {
+        return 'CREATE DATABASE ' . $name;
+    }
+
+    /**
+     * drop an existing database
+     *
+     * @param string $name name of the database that should be dropped
+     * @return string
+     * @override
+     */
+    public function getDropDatabaseSQL($name)
+    {
+        return 'DROP DATABASE ' . $name;
+    }
+
+    /**
+     * @override
+     */
+    public function supportsCreateDropDatabase()
+    {
+        return false;
+    }
+
+    /**
+     * @override
+     */
+    public function getDropForeignKeySQL($foreignKey, $table)
+    {
+        if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
+            $foreignKey = $foreignKey->getQuotedName($this);
+        }
+
+        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+            $table = $table->getQuotedName($this);
+        }
+
+        return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
+    }
+
+    /**
+     * @override
+     */
+    public function getDropIndexSQL($index, $table=null)
+    {
+        if ($index instanceof \Doctrine\DBAL\Schema\Index) {
+            $index_ = $index;
+            $index = $index->getQuotedName($this);
+        } else if (!is_string($index)) {
+            throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
+        }
+
+        if (!isset($table)) {
+            return 'DROP INDEX ' . $index;
+        } else {
+            if ($table instanceof \Doctrine\DBAL\Schema\Table) {
+                $table = $table->getQuotedName($this);
+            }
+
+            return "IF EXISTS (SELECT * FROM sysobjects WHERE name = '$index')
+						ALTER TABLE " . $table . " DROP CONSTRAINT " . $index . "
+					ELSE
+						DROP INDEX " . $index . " ON " . $table;
+        }
+    }
+
+    /**
+     * @override
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        // @todo does other code breaks because of this?
+        // foce primary keys to be not null
+        foreach ($columns as &$column) {
+            if (isset($column['primary']) && $column['primary']) {
+                $column['notnull'] = true;
+            }
+        }
+
+        $columnListSql = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['uniqueConstraints']) && !empty($options['uniqueConstraints'])) {
+            foreach ($options['uniqueConstraints'] as $name => $definition) {
+                $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
+            }
+        }
+
+        if (isset($options['primary']) && !empty($options['primary'])) {
+            $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
+        }
+
+        $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
+
+        $check = $this->getCheckDeclarationSQL($columns);
+        if (!empty($check)) {
+            $query .= ', ' . $check;
+        }
+        $query .= ')';
+
+        $sql[] = $query;
+
+        if (isset($options['indexes']) && !empty($options['indexes'])) {
+            foreach ($options['indexes'] AS $index) {
+                $sql[] = $this->getCreateIndexSQL($index, $tableName);
+            }
+        }
+
+        if (isset($options['foreignKeys'])) {
+            foreach ((array) $options['foreignKeys'] AS $definition) {
+                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @override
+     */
+    public function getUniqueConstraintDeclarationSQL($name, Index $index)
+    {
+        $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index);
+
+        $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
+
+        return $constraint;
+    }
+
+    /**
+     * @override
+     */
+    public function getCreateIndexSQL(Index $index, $table)
+    {
+        $constraint = parent::getCreateIndexSQL($index, $table);
+
+        if ($index->isUnique()) {
+            $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
+        }
+
+        return $constraint;
+    }
+
+    /**
+     * Extend unique key constraint with required filters
+     *
+     * @param string $sql
+     * @param Index $index
+     * @return string
+     */
+    private function _appendUniqueConstraintDefinition($sql, Index $index)
+    {
+        $fields = array();
+        foreach ($index->getColumns() as $field => $definition) {
+            if (!is_array($definition)) {
+                $field = $definition;
+            }
+
+            $fields[] = $field . ' IS NOT NULL';
+        }
+
+        return $sql . ' WHERE ' . implode(' AND ', $fields);
+    }
+
+    /**
+     * @override
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $queryParts = array();
+        $sql = array();
+        $columnSql = array();
+
+        if ($diff->newName !== false) {
+            $queryParts[] = 'RENAME TO ' . $diff->newName;
+        }
+
+        foreach ($diff->addedColumns AS $fieldName => $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+        }
+
+        foreach ($diff->removedColumns AS $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
+        }
+
+        foreach ($diff->changedColumns AS $columnDiff) {
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
+            $column = $columnDiff->column;
+            $queryParts[] = 'ALTER COLUMN ' .
+                    $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+        }
+
+        foreach ($diff->renamedColumns AS $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $sql[] = "sp_RENAME '". $diff->name. ".". $oldColumnName . "' , '".$column->getQuotedName($this)."', 'COLUMN'";
+            $queryParts[] = 'ALTER COLUMN ' .
+                    $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+        }
+
+        $tableSql = array();
+
+        if ($this->onSchemaAlterTable($diff, $tableSql)) {
+            return array_merge($tableSql, $columnSql);
+        }
+
+        foreach ($queryParts as $query) {
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+        }
+
+        $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    /**
+     * @override
+     */
+    public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
+    {
+        return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
+    }
+
+    /**
+     * @override
+     */
+    public function getShowDatabasesSQL()
+    {
+        return 'SHOW DATABASES';
+    }
+
+    /**
+     * @override
+     */
+    public function getListTablesSQL()
+    {
+        // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
+        return "SELECT name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' ORDER BY name";
+    }
+
+    /**
+     * @override
+     */
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        return "exec sp_columns @table_name = '" . $table . "'";
+    }
+
+    /**
+     * @override
+     */
+    public function getListTableForeignKeysSQL($table, $database = null)
+    {
+        return "SELECT f.name AS ForeignKey,
+                SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
+                OBJECT_NAME (f.parent_object_id) AS TableName,
+                COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
+                SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
+                OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
+                COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
+                f.delete_referential_action_desc,
+                f.update_referential_action_desc
+                FROM sys.foreign_keys AS f
+                INNER JOIN sys.foreign_key_columns AS fc
+                INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
+                ON f.OBJECT_ID = fc.constraint_object_id
+                WHERE OBJECT_NAME (f.parent_object_id) = '" . $table . "'";
+    }
+
+    /**
+     * @override
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        return "exec sp_helpindex '" . $table . "'";
+    }
+
+    /**
+     * @override
+     */
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    /**
+     * @override
+     */
+    public function getListViewsSQL($database)
+    {
+        return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name";
+    }
+
+    /**
+     * @override
+     */
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW ' . $name;
+    }
+
+    /**
+     * Returns the regular expression operator.
+     *
+     * @return string
+     * @override
+     */
+    public function getRegexpExpression()
+    {
+        return 'RLIKE';
+    }
+
+    /**
+     * Returns global unique identifier
+     *
+     * @return string to get global unique identifier
+     * @override
+     */
+    public function getGuidExpression()
+    {
+        return 'UUID()';
+    }
+
+    /**
+     * @override
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos == false) {
+            return 'CHARINDEX(' . $substr . ', ' . $str . ')';
+        } else {
+            return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')';
+        }
+    }
+
+    /**
+     * @override
+     */
+    public function getModExpression($expression1, $expression2)
+    {
+        return $expression1 . ' % ' . $expression2;
+    }
+
+    /**
+     * @override
+     */
+    public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
+    {
+        $trimFn = '';
+
+        if (!$char) {
+            if ($pos == self::TRIM_LEADING) {
+                $trimFn = 'LTRIM';
+            } else if ($pos == self::TRIM_TRAILING) {
+                $trimFn = 'RTRIM';
+            } else {
+                return 'LTRIM(RTRIM(' . $str . '))';
+            }
+
+            return $trimFn . '(' . $str . ')';
+        } else {
+            /** Original query used to get those expressions
+              declare @c varchar(100) = 'xxxBarxxx', @trim_char char(1) = 'x';
+              declare @pat varchar(10) = '%[^' + @trim_char + ']%';
+              select @c as string
+              , @trim_char as trim_char
+              , stuff(@c, 1, patindex(@pat, @c) - 1, null) as trim_leading
+              , reverse(stuff(reverse(@c), 1, patindex(@pat, reverse(@c)) - 1, null)) as trim_trailing
+              , reverse(stuff(reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null)), 1, patindex(@pat, reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null))) - 1, null)) as trim_both;
+             */
+            $pattern = "'%[^' + $char + ']%'";
+
+            if ($pos == self::TRIM_LEADING) {
+                return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)';
+            } else if ($pos == self::TRIM_TRAILING) {
+                return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))';
+            } else {
+                return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null))) - 1, null))';
+            }
+        }
+    }
+
+    /**
+     * @override
+     */
+    public function getConcatExpression()
+    {
+        $args = func_get_args();
+        return '(' . implode(' + ', $args) . ')';
+    }
+
+    public function getListDatabasesSQL()
+    {
+        return 'SELECT * FROM SYS.DATABASES';
+    }
+
+    /**
+     * @override
+     */
+    public function getSubstringExpression($value, $from, $len = null)
+    {
+        if (!is_null($len)) {
+            return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $len . ')';
+        }
+        return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)';
+    }
+
+    /**
+     * @override
+     */
+    public function getLengthExpression($column)
+    {
+        return 'LEN(' . $column . ')';
+    }
+
+    /**
+     * @override
+     */
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    /**
+     * @override
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /** @override */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
+    }
+
+    /** @override */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'TEXT';
+    }
+
+    /**
+     * @override
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        $autoinc = '';
+        if (!empty($columnDef['autoincrement'])) {
+            $autoinc = ' IDENTITY';
+        }
+        $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
+
+        return $unsigned . $autoinc;
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATETIME';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATETIME';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATETIME';
+    }
+
+    /**
+     * @override
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'BIT';
+    }
+
+    /**
+     * Adds an adapter-specific LIMIT clause to the SELECT statement.
+     *
+     * @param string $query
+     * @param integer $limit
+     * @param integer $offset
+     * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
+     * @return string
+     */
+    protected function doModifyLimitQuery($query, $limit, $offset = null)
+    {
+        if ($limit > 0) {
+            if ($offset == 0) {
+                $query = preg_replace('/^(SELECT\s(DISTINCT\s)?)/i', '\1TOP ' . $limit . ' ', $query);
+            } else {
+                $orderby = stristr($query, 'ORDER BY');
+
+                if (!$orderby) {
+                    $over = 'ORDER BY (SELECT 0)';
+                } else {
+                    $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby);
+                }
+
+                // Remove ORDER BY clause from $query
+                $query = preg_replace('/\s+ORDER BY(.*)/', '', $query);
+                $query = preg_replace('/^SELECT\s/', '', $query);
+
+                $start = $offset + 1;
+                $end = $offset + $limit;
+
+                $query = "SELECT * FROM (SELECT ROW_NUMBER() OVER ($over) AS \"doctrine_rownum\", $query) AS doctrine_tbl WHERE \"doctrine_rownum\" BETWEEN $start AND $end";
+            }
+        }
+
+        return $query;
+    }
+
+    /**
+     * @override
+     */
+    public function supportsLimitOffset()
+    {
+        return false;
+    }
+
+    /**
+     * @override
+     */
+    public function convertBooleans($item)
+    {
+        if (is_array($item)) {
+            foreach ($item as $key => $value) {
+                if (is_bool($value) || is_numeric($item)) {
+                    $item[$key] = ($value) ? 1 : 0;
+                }
+            }
+        } else {
+            if (is_bool($item) || is_numeric($item)) {
+                $item = ($item) ? 1 : 0;
+            }
+        }
+        return $item;
+    }
+
+    /**
+     * @override
+     */
+    public function getCreateTemporaryTableSnippetSQL()
+    {
+        return "CREATE TABLE";
+    }
+
+    /**
+     * @override
+     */
+    public function getTemporaryTableName($tableName)
+    {
+        return '#' . $tableName;
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeFormatString()
+    {
+        return 'Y-m-d H:i:s.000';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateFormatString()
+    {
+        return 'Y-m-d H:i:s.000';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeFormatString()
+    {
+        return 'Y-m-d H:i:s.000';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTzFormatString()
+    {
+        return $this->getDateTimeFormatString();
+    }
+
+    /**
+     * Get the platform name for this instance
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'mssql';
+    }
+
+    /**
+     * @override
+     */
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'bigint' => 'bigint',
+            'numeric' => 'decimal',
+            'bit' => 'boolean',
+            'smallint' => 'smallint',
+            'decimal' => 'decimal',
+            'smallmoney' => 'integer',
+            'int' => 'integer',
+            'tinyint' => 'smallint',
+            'money' => 'integer',
+            'float' => 'float',
+            'real' => 'float',
+            'double' => 'float',
+            'double precision' => 'float',
+            'datetimeoffset' => 'datetimetz',
+            'smalldatetime' => 'datetime',
+            'datetime' => 'datetime',
+            'char' => 'string',
+            'varchar' => 'string',
+            'text' => 'text',
+            'nchar' => 'string',
+            'nvarchar' => 'string',
+            'ntext' => 'text',
+            'binary' => 'text',
+            'varbinary' => 'blob',
+            'image' => 'text',
+        );
+    }
+
+    /**
+     * Generate SQL to create a new savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function createSavePoint($savepoint)
+    {
+        return 'SAVE TRANSACTION ' . $savepoint;
+    }
+
+    /**
+     * Generate SQL to release a savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function releaseSavePoint($savepoint)
+    {
+        return '';
+    }
+
+    /**
+     * Generate SQL to rollback a savepoint
+     *
+     * @param string $savepoint
+     * @return string
+     */
+    public function rollbackSavePoint($savepoint)
+    {
+        return 'ROLLBACK TRANSACTION ' . $savepoint;
+    }
+
+    /**
+     * @override
+     */
+    public function appendLockHint($fromClause, $lockMode)
+    {
+        // @todo coorect
+        if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ) {
+            return $fromClause . ' WITH (tablockx)';
+        } else if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) {
+            return $fromClause . ' WITH (tablockx)';
+        } else {
+            return $fromClause;
+        }
+    }
+
+    /**
+     * @override
+     */
+    public function getForUpdateSQL()
+    {
+        return ' ';
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\MsSQLKeywords';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function quoteSingleIdentifier($str)
+    {
+        return "[" . str_replace("]", "][", $str) . "]";
+    }
+
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        return 'TRUNCATE TABLE '.$tableName;
+    }
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'VARBINARY(MAX)';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SqlitePlatform.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SqlitePlatform.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SqlitePlatform.php	(revision 345)
@@ -0,0 +1,519 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\DBALException;
+
+/**
+ * The SqlitePlatform class describes the specifics and dialects of the SQLite
+ * database platform.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Rename: SQLitePlatform
+ */
+class SqlitePlatform extends AbstractPlatform
+{
+    /**
+     * returns the regular expression operator
+     *
+     * @return string
+     * @override
+     */
+    public function getRegexpExpression()
+    {
+        return 'RLIKE';
+    }
+
+    /**
+     * Return string to call a variable with the current timestamp inside an SQL statement
+     * There are three special variables for current date and time.
+     *
+     * @return string       sqlite function as string
+     * @override
+     */
+    public function getNowExpression($type = 'timestamp')
+    {
+        switch ($type) {
+            case 'time':
+                return 'time(\'now\')';
+            case 'date':
+                return 'date(\'now\')';
+            case 'timestamp':
+            default:
+                return 'datetime(\'now\')';
+        }
+    }
+
+    /**
+     * Trim a string, leading/trailing/both and with a given char which defaults to space.
+     *
+     * @param string $str
+     * @param int $pos
+     * @param string $char
+     * @return string
+     */
+    public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
+    {
+        $trimFn = '';
+        $trimChar = ($char != false) ? (', ' . $char) : '';
+
+        if ($pos == self::TRIM_LEADING) {
+            $trimFn = 'LTRIM';
+        } else if($pos == self::TRIM_TRAILING) {
+            $trimFn = 'RTRIM';
+        } else {
+            $trimFn = 'TRIM';
+        }
+
+        return $trimFn . '(' . $str . $trimChar . ')';
+    }
+
+    /**
+     * return string to call a function to get a substring inside an SQL statement
+     *
+     * Note: Not SQL92, but common functionality.
+     *
+     * SQLite only supports the 2 parameter variant of this function
+     *
+     * @param string $value         an sql string literal or column name/alias
+     * @param integer $position     where to start the substring portion
+     * @param integer $length       the substring portion length
+     * @return string               SQL substring function with given parameters
+     * @override
+     */
+    public function getSubstringExpression($value, $position, $length = null)
+    {
+        if ($length !== null) {
+            return 'SUBSTR(' . $value . ', ' . $position . ', ' . $length . ')';
+        }
+        return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))';
+    }
+
+    /**
+     * returns the position of the first occurrence of substring $substr in string $str
+     *
+     * @param string $substr    literal string to find
+     * @param string $str       literal string
+     * @param int    $pos       position to start at, beginning of string by default
+     * @return integer
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos == false) {
+            return 'LOCATE('.$str.', '.$substr.')';
+        } else {
+            return 'LOCATE('.$str.', '.$substr.', '.$startPos.')';
+        }
+    }
+
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return 'ROUND(JULIANDAY('.$date1 . ')-JULIANDAY('.$date2.'))';
+    }
+
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return "DATE(" . $date . ",'+". $days . " day')";
+    }
+
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return "DATE(" . $date . ",'-". $days . " day')";
+    }
+
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return "DATE(" . $date . ",'+". $months . " month')";
+    }
+
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return "DATE(" . $date . ",'-". $months . " month')";
+    }
+
+    protected function _getTransactionIsolationLevelSQL($level)
+    {
+        switch ($level) {
+            case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED:
+                return 0;
+            case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED:
+            case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ:
+            case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE:
+                return 1;
+            default:
+                return parent::_getTransactionIsolationLevelSQL($level);
+        }
+    }
+
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    /**
+     * @override
+     */
+    public function prefersIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * @override
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'BOOLEAN';
+    }
+
+    /**
+     * @override
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        return $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        return $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getTinyIntTypeDeclarationSql(array $field)
+    {
+        return $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getMediumIntTypeDeclarationSql(array $field)
+    {
+        return $this->_getCommonIntegerTypeDeclarationSQL($field);
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATETIME';
+    }
+
+    /**
+     * @override
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * @override
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME';
+    }
+
+    /**
+     * @override
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        return 'INTEGER';
+    }
+
+    /**
+     * create a new table
+     *
+     * @param string $name   Name of the database that should be created
+     * @param array $fields  Associative array that contains the definition of each field of the new table
+     *                       The indexes of the array entries are the names of the fields of the table an
+     *                       the array entry values are associative arrays like those that are meant to be
+     *                       passed with the field definitions to get[Type]Declaration() functions.
+     *                          array(
+     *                              'id' => array(
+     *                                  'type' => 'integer',
+     *                                  'unsigned' => 1
+     *                                  'notnull' => 1
+     *                                  'default' => 0
+     *                              ),
+     *                              'name' => array(
+     *                                  'type' => 'text',
+     *                                  'length' => 12
+     *                              ),
+     *                              'password' => array(
+     *                                  'type' => 'text',
+     *                                  'length' => 12
+     *                              )
+     *                          );
+     * @param array $options  An associative array of table options:
+     *
+     * @return void
+     * @override
+     */
+    protected function _getCreateTableSQL($name, array $columns, array $options = array())
+    {
+        $name = str_replace(".", "__", $name);
+        $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['primary']) && ! empty($options['primary'])) {
+            $keyColumns = array_unique(array_values($options['primary']));
+            $keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns);
+            $queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')';
+        }
+
+        $query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')';
+
+        if (isset($options['indexes']) && ! empty($options['indexes'])) {
+            foreach ($options['indexes'] as $index => $indexDef) {
+                $query[] = $this->getCreateIndexSQL($indexDef, $name);
+            }
+        }
+        if (isset($options['unique']) && ! empty($options['unique'])) {
+            foreach ($options['unique'] as $index => $indexDef) {
+                $query[] = $this->getCreateIndexSQL($indexDef, $name);
+            }
+        }
+        return $query;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
+    }
+
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'CLOB';
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        $table = str_replace(".", "__", $table);
+        return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = '$table' AND sql NOT NULL ORDER BY name";
+    }
+
+    public function getListTableColumnsSQL($table, $currentDatabase = null)
+    {
+        $table = str_replace(".", "__", $table);
+        return "PRAGMA table_info($table)";
+    }
+
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        $table = str_replace(".", "__", $table);
+        return "PRAGMA index_list($table)";
+    }
+
+    public function getListTablesSQL()
+    {
+        return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' "
+             . "UNION ALL SELECT name FROM sqlite_temp_master "
+             . "WHERE type = 'table' ORDER BY name";
+    }
+
+    public function getListViewsSQL($database)
+    {
+        return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL";
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW '. $name;
+    }
+
+    /**
+     * SQLite does support foreign key constraints, but only in CREATE TABLE statements...
+     * This really limits their usefulness and requires SQLite specific handling, so
+     * we simply say that SQLite does NOT support foreign keys for now...
+     *
+     * @return boolean FALSE
+     * @override
+     */
+    public function supportsForeignKeyConstraints()
+    {
+        return false;
+    }
+
+    public function supportsAlterTable()
+    {
+        return false;
+    }
+
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * Get the platform name for this instance
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'sqlite';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        $tableName = str_replace(".", "__", $tableName);
+        return 'DELETE FROM '.$tableName;
+    }
+
+    /**
+     * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction()
+     *
+     * @param  int|float $value
+     * @return float
+     */
+    static public function udfSqrt($value)
+    {
+        return sqrt($value);
+    }
+
+    /**
+     * User-defined function for Sqlite that implements MOD(a, b)
+     */
+    static public function udfMod($a, $b)
+    {
+        return ($a % $b);
+    }
+
+    /**
+     * @param string $str
+     * @param string $substr
+     * @param int $offset
+     */
+    static public function udfLocate($str, $substr, $offset = 0)
+    {
+        $pos = strpos($str, $substr, $offset);
+        if ($pos !== false) {
+            return $pos+1;
+        }
+        return 0;
+    }
+
+    public function getForUpdateSql()
+    {
+        return '';
+    }
+
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'boolean'          => 'boolean',
+            'tinyint'          => 'boolean',
+            'smallint'         => 'smallint',
+            'mediumint'        => 'integer',
+            'int'              => 'integer',
+            'integer'          => 'integer',
+            'serial'           => 'integer',
+            'bigint'           => 'bigint',
+            'bigserial'        => 'bigint',
+            'clob'             => 'text',
+            'tinytext'         => 'text',
+            'mediumtext'       => 'text',
+            'longtext'         => 'text',
+            'text'             => 'text',
+            'varchar'          => 'string',
+            'longvarchar'      => 'string',
+            'varchar2'         => 'string',
+            'nvarchar'         => 'string',
+            'image'            => 'string',
+            'ntext'            => 'string',
+            'char'             => 'string',
+            'date'             => 'date',
+            'datetime'         => 'datetime',
+            'timestamp'        => 'datetime',
+            'time'             => 'time',
+            'float'            => 'float',
+            'double'           => 'float',
+            'double precision' => 'float',
+            'real'             => 'float',
+            'decimal'          => 'decimal',
+            'numeric'          => 'decimal',
+            'blob'             => 'blob',
+        );
+    }
+
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords';
+    }
+
+    /**
+     * Gets the SQL Snippet used to declare a BLOB column type.
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'BLOB';
+    }
+
+    public function getTemporaryTableName($tableName)
+    {
+        $tableName = str_replace(".", "__", $tableName);
+        return $tableName;
+    }
+
+    /**
+     * Sqlite Platform emulates schema by underscoring each dot and generating tables
+     * into the default database.
+     *
+     * This hack is implemented to be able to use SQLite as testdriver when
+     * using schema supporting databases.
+     *
+     * @return bool
+     */
+    public function canEmulateSchemas()
+    {
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Connection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Connection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Connection.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Portability;
+
+use Doctrine\Common\EventManager;
+use Doctrine\DBAL\Configuration;
+use Doctrine\DBAL\Driver;
+use Doctrine\DBAL\Cache\QueryCacheProfile;
+
+class Connection extends \Doctrine\DBAL\Connection
+{
+    const PORTABILITY_ALL               = 255;
+    const PORTABILITY_NONE              = 0;
+    const PORTABILITY_RTRIM             = 1;
+    const PORTABILITY_EMPTY_TO_NULL     = 4;
+    const PORTABILITY_FIX_CASE          = 8;
+
+    const PORTABILITY_ORACLE            = 9;
+    const PORTABILITY_POSTGRESQL        = 13;
+    const PORTABILITY_SQLITE            = 13;
+    const PORTABILITY_OTHERVENDORS      = 12;
+
+    /**
+     * @var int
+     */
+    private $portability = self::PORTABILITY_NONE;
+
+    /**
+     * @var int
+     */
+    private $case;
+
+    public function connect()
+    {
+        $ret = parent::connect();
+        if ($ret) {
+            $params = $this->getParams();
+            if (isset($params['portability'])) {
+                if ($this->_platform->getName() === "oracle") {
+                    $params['portability'] = $params['portability'] & self::PORTABILITY_ORACLE;
+                } else if ($this->_platform->getName() === "postgresql") {
+                    $params['portability'] = $params['portability'] & self::PORTABILITY_POSTGRESQL;
+                } else if ($this->_platform->getName() === "sqlite") {
+                    $params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE;
+                } else {
+                    $params['portability'] = $params['portability'] & self::PORTABILITY_OTHERVENDORS;
+                }
+                $this->portability = $params['portability'];
+            }
+            if (isset($params['fetch_case']) && $this->portability & self::PORTABILITY_FIX_CASE) {
+                if ($this->_conn instanceof \Doctrine\DBAL\Driver\PDOConnection) {
+                    // make use of c-level support for case handling
+                    $this->_conn->setAttribute(\PDO::ATTR_CASE, $params['fetch_case']);
+                } else {
+                    $this->case = ($params['fetch_case'] == \PDO::CASE_LOWER) ? CASE_LOWER : CASE_UPPER;
+                }
+            }
+        }
+        return $ret;
+    }
+
+    public function getPortability()
+    {
+        return $this->portability;
+    }
+
+    public function getFetchCase()
+    {
+        return $this->case;
+    }
+
+    public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
+    {
+        return new Statement(parent::executeQuery($query, $params, $types, $qcp), $this);
+    }
+
+    /**
+     * Prepares an SQL statement.
+     *
+     * @param string $statement The SQL statement to prepare.
+     * @return Doctrine\DBAL\Driver\Statement The prepared statement.
+     */
+    public function prepare($statement)
+    {
+        return new Statement(parent::prepare($statement), $this);
+    }
+
+    public function query()
+    {
+        $this->connect();
+
+        $stmt = call_user_func_array(array($this->_conn, 'query'), func_get_args());
+        return new Statement($stmt, $this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Statement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Statement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Portability/Statement.php	(revision 345)
@@ -0,0 +1,190 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Portability;
+
+use PDO;
+
+/**
+ * Portability Wrapper for a Statement
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Statement implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
+{
+
+    /**
+     * @var int
+     */
+    private $portability;
+
+    /**
+     * @var Doctrine\DBAL\Driver\Statement
+     */
+    private $stmt;
+
+    /**
+     * @var int
+     */
+    private $case;
+
+    /**
+     * @var int
+     */
+    private $defaultFetchStyle = PDO::FETCH_BOTH;
+
+    /**
+     * Wraps <tt>Statement</tt> and applies portability measures
+     *
+     * @param Doctrine\DBAL\Driver\Statement $stmt
+     * @param Doctrine\DBAL\Connection $conn
+     */
+    public function __construct($stmt, Connection $conn)
+    {
+        $this->stmt = $stmt;
+        $this->portability = $conn->getPortability();
+        $this->case = $conn->getFetchCase();
+    }
+
+    public function bindParam($column, &$variable, $type = null)
+    {
+        return $this->stmt->bindParam($column, $variable, $type);
+    }
+
+    public function bindValue($param, $value, $type = null)
+    {
+        return $this->stmt->bindValue($param, $value, $type);
+    }
+
+    public function closeCursor()
+    {
+        return $this->stmt->closeCursor();
+    }
+
+    public function columnCount()
+    {
+        return $this->stmt->columnCount();
+    }
+
+    public function errorCode()
+    {
+        return $this->stmt->errorCode();
+    }
+
+    public function errorInfo()
+    {
+        return $this->stmt->errorInfo();
+    }
+
+    public function execute($params = null)
+    {
+        return $this->stmt->execute($params);
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        $this->defaultFetchStyle = $fetchStyle;
+    }
+
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $row = $this->stmt->fetch($fetchStyle);
+
+        $row = $this->fixRow($row,
+            $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM),
+            !is_null($this->case) && ($fetchStyle == PDO::FETCH_ASSOC || $fetchStyle == PDO::FETCH_BOTH) && ($this->portability & Connection::PORTABILITY_FIX_CASE)
+        );
+
+        return $row;
+    }
+
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH, $columnIndex = 0)
+    {
+        if ($columnIndex != 0) {
+            $rows = $this->stmt->fetchAll($fetchStyle, $columnIndex);
+        } else {
+            $rows = $this->stmt->fetchAll($fetchStyle);
+        }
+
+        $iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM);
+        $fixCase = !is_null($this->case) && ($fetchStyle == PDO::FETCH_ASSOC || $fetchStyle == PDO::FETCH_BOTH) && ($this->portability & Connection::PORTABILITY_FIX_CASE);
+        if (!$iterateRow && !$fixCase) {
+            return $rows;
+        }
+
+        foreach ($rows AS $num => $row) {
+            $rows[$num] = $this->fixRow($row, $iterateRow, $fixCase);
+        }
+
+        return $rows;
+    }
+
+    protected function fixRow($row, $iterateRow, $fixCase)
+    {
+        if (!$row) {
+            return $row;
+        }
+
+        if ($fixCase) {
+            $row = array_change_key_case($row, $this->case);
+        }
+
+        if ($iterateRow) {
+            foreach ($row AS $k => $v) {
+                if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $v === '') {
+                    $row[$k] = null;
+                } else if (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($v)) {
+                    $row[$k] = rtrim($v);
+                }
+            }
+        }
+        return $row;
+    }
+
+    public function fetchColumn($columnIndex = 0)
+    {
+        $value = $this->stmt->fetchColumn($columnIndex);
+
+        if ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) {
+            if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') {
+                $value = null;
+            } else if (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($value)) {
+                $value = rtrim($value);
+            }
+        }
+
+        return $value;
+    }
+
+    public function rowCount()
+    {
+        return $this->stmt->rowCount();
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/CompositeExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/CompositeExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/CompositeExpression.php	(revision 345)
@@ -0,0 +1,130 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Query\Expression;
+
+/**
+ * Composite expression is responsible to build a group of similar expression.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.1
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class CompositeExpression implements \Countable
+{
+    /**
+     * Constant that represents an AND composite expression
+     */
+    const TYPE_AND = 'AND';
+
+    /**
+     * Constant that represents an OR composite expression
+     */
+    const TYPE_OR  = 'OR';
+
+    /**
+     * @var string Holds the instance type of composite expression
+     */
+    private $type;
+
+    /**
+     * @var array Each expression part of the composite expression
+     */
+    private $parts = array();
+
+    /**
+     * Constructor.
+     *
+     * @param string $type Instance type of composite expression
+     * @param array $parts Composition of expressions to be joined on composite expression
+     */
+    public function __construct($type, array $parts = array())
+    {
+        $this->type = $type;
+
+        $this->addMultiple($parts);
+    }
+
+    /**
+     * Adds multiple parts to composite expression.
+     *
+     * @param array $args
+     *
+     * @return CompositeExpression
+     */
+    public function addMultiple(array $parts = array())
+    {
+        foreach ((array) $parts as $part) {
+            $this->add($part);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds an expression to composite expression.
+     *
+     * @param mixed $part
+     * @return CompositeExpression
+     */
+    public function add($part)
+    {
+        if ( ! empty($part) || ($part instanceof self && $part->count() > 0)) {
+            $this->parts[] = $part;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Retrieves the amount of expressions on composite expression.
+     *
+     * @return integer
+     */
+    public function count()
+    {
+        return count($this->parts);
+    }
+
+    /**
+     * Retrieve the string representation of this composite expression.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        if (count($this->parts) === 1) {
+            return (string) $this->parts[0];
+        }
+
+        return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')';
+    }
+
+    /**
+     * Return type of this composite expression (AND/OR)
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php	(revision 345)
@@ -0,0 +1,264 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Query\Expression;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * ExpressionBuilder class is responsible to dynamically create SQL query parts.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.1
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ExpressionBuilder
+{
+    const EQ  = '=';
+    const NEQ = '<>';
+    const LT  = '<';
+    const LTE = '<=';
+    const GT  = '>';
+    const GTE = '>=';
+
+    /**
+     * @var Doctrine\DBAL\Connection DBAL Connection
+     */
+    private $connection = null;
+
+    /**
+     * Initializes a new <tt>ExpressionBuilder</tt>.
+     *
+     * @param Doctrine\DBAL\Connection $connection DBAL Connection
+     */
+    public function __construct(Connection $connection)
+    {
+        $this->connection = $connection;
+    }
+
+    /**
+     * Creates a conjunction of the given boolean expressions.
+     *
+     * Example:
+     *
+     *     [php]
+     *     // (u.type = ?) AND (u.role = ?)
+     *     $expr->andX('u.type = ?', 'u.role = ?'));
+     *
+     * @param mixed $x Optional clause. Defaults = null, but requires
+     *                 at least one defined when converting to string.
+     * @return CompositeExpression
+     */
+    public function andX($x = null)
+    {
+        return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
+    }
+
+    /**
+     * Creates a disjunction of the given boolean expressions.
+     *
+     * Example:
+     *
+     *     [php]
+     *     // (u.type = ?) OR (u.role = ?)
+     *     $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?'));
+     *
+     * @param mixed $x Optional clause. Defaults = null, but requires
+     *                 at least one defined when converting to string.
+     * @return CompositeExpression
+     */
+    public function orX($x = null)
+    {
+        return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args());
+    }
+
+    /**
+     * Creates a comparison expression.
+     *
+     * @param mixed $x Left expression
+     * @param string $operator One of the ExpressionBuikder::* constants.
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function comparison($x, $operator, $y)
+    {
+        return $x . ' ' . $operator . ' ' . $y;
+    }
+
+    /**
+     * Creates an equality comparison expression with the given arguments.
+     *
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> = <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id = ?
+     *     $expr->eq('u.id', '?');
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function eq($x, $y)
+    {
+        return $this->comparison($x, self::EQ, $y);
+    }
+
+    /**
+     * Creates a non equality comparison expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> <> <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id <> 1
+     *     $q->where($q->expr()->neq('u.id', '1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function neq($x, $y)
+    {
+        return $this->comparison($x, self::NEQ, $y);
+    }
+
+    /**
+     * Creates a lower-than comparison expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> < <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id < ?
+     *     $q->where($q->expr()->lt('u.id', '?'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function lt($x, $y)
+    {
+        return $this->comparison($x, self::LT, $y);
+    }
+
+    /**
+     * Creates a lower-than-equal comparison expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> <= <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id <= ?
+     *     $q->where($q->expr()->lte('u.id', '?'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function lte($x, $y)
+    {
+        return $this->comparison($x, self::LTE, $y);
+    }
+
+    /**
+     * Creates a greater-than comparison expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> > <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id > ?
+     *     $q->where($q->expr()->gt('u.id', '?'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function gt($x, $y)
+    {
+        return $this->comparison($x, self::GT, $y);
+    }
+
+    /**
+     * Creates a greater-than-equal comparison expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> >= <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id >= ?
+     *     $q->where($q->expr()->gte('u.id', '?'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return string
+     */
+    public function gte($x, $y)
+    {
+        return $this->comparison($x, self::GTE, $y);
+    }
+
+    /**
+     * Creates an IS NULL expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by IS NULL
+     *
+     * @return string
+     */
+    public function isNull($x)
+    {
+        return $x . ' IS NULL';
+    }
+
+    /**
+     * Creates an IS NOT NULL expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by IS NOT NULL
+     *
+     * @return string
+     */
+    public function isNotNull($x)
+    {
+        return $x . ' IS NOT NULL';
+    }
+
+    /**
+     * Creates a LIKE() comparison expression with the given arguments.
+     *
+     * @param string $x Field in string format to be inspected by LIKE() comparison.
+     * @param mixed $y Argument to be used in LIKE() comparison.
+     *
+     * @return string
+     */
+    public function like($x, $y)
+    {
+        return $this->comparison($x, 'LIKE', $y);
+    }
+
+    /**
+     * Quotes a given input parameter.
+     *
+     * @param mixed $input Parameter to be quoted.
+     * @param string $type Type of the parameter.
+     *
+     * @return string
+     */
+    public function literal($input, $type = null)
+    {
+        return $this->connection->quote($input, $type);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryBuilder.php	(revision 345)
@@ -0,0 +1,1091 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Query;
+
+use Doctrine\DBAL\Query\Expression\CompositeExpression,
+    Doctrine\DBAL\Connection;
+
+/**
+ * QueryBuilder class is responsible to dynamically create SQL queries.
+ *
+ * Important: Verify that every feature you use will work with your database vendor.
+ * SQL Query Builder does not attempt to validate the generated SQL at all.
+ *
+ * The query builder does no validation whatsoever if certain features even work with the
+ * underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements
+ * even if some vendors such as MySQL support it.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.1
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QueryBuilder
+{
+    /* The query types. */
+    const SELECT = 0;
+    const DELETE = 1;
+    const UPDATE = 2;
+
+    /** The builder states. */
+    const STATE_DIRTY = 0;
+    const STATE_CLEAN = 1;
+
+    /**
+     * @var Doctrine\DBAL\Connection DBAL Connection
+     */
+    private $connection = null;
+
+    /**
+     * @var array The array of SQL parts collected.
+     */
+    private $sqlParts = array(
+        'select'  => array(),
+        'from'    => array(),
+        'join'    => array(),
+        'set'     => array(),
+        'where'   => null,
+        'groupBy' => array(),
+        'having'  => null,
+        'orderBy' => array()
+    );
+
+    /**
+     * @var string The complete SQL string for this query.
+     */
+    private $sql;
+
+    /**
+     * @var array The query parameters.
+     */
+    private $params = array();
+
+    /**
+     * @var array The parameter type map of this query.
+     */
+    private $paramTypes = array();
+
+    /**
+     * @var integer The type of query this is. Can be select, update or delete.
+     */
+    private $type = self::SELECT;
+
+    /**
+     * @var integer The state of the query object. Can be dirty or clean.
+     */
+    private $state = self::STATE_CLEAN;
+
+    /**
+     * @var integer The index of the first result to retrieve.
+     */
+    private $firstResult = null;
+
+    /**
+     * @var integer The maximum number of results to retrieve.
+     */
+    private $maxResults = null;
+
+    /**
+     * The counter of bound parameters used with {@see bindValue)
+     *
+     * @var int
+     */
+    private $boundCounter = 0;
+
+    /**
+     * Initializes a new <tt>QueryBuilder</tt>.
+     *
+     * @param Doctrine\DBAL\Connection $connection DBAL Connection
+     */
+    public function __construct(Connection $connection)
+    {
+        $this->connection = $connection;
+    }
+
+    /**
+     * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
+     * This producer method is intended for convenient inline usage. Example:
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('users', 'u')
+     *         ->where($qb->expr()->eq('u.id', 1));
+     * </code>
+     *
+     * For more complex expression construction, consider storing the expression
+     * builder object in a local variable.
+     *
+     * @return Doctrine\DBAL\Query\ExpressionBuilder
+     */
+    public function expr()
+    {
+        return $this->connection->getExpressionBuilder();
+    }
+
+    /**
+     * Get the type of the currently built query.
+     *
+     * @return integer
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Get the associated DBAL Connection for this query builder.
+     *
+     * @return Doctrine\DBAL\Connection
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Get the state of this query builder instance.
+     *
+     * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
+     */
+    public function getState()
+    {
+        return $this->state;
+    }
+
+    /**
+     * Execute this query using the bound parameters and their types.
+     *
+     * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
+     * for insert, update and delete statements.
+     *
+     * @return mixed
+     */
+    public function execute()
+    {
+        if ($this->type == self::SELECT) {
+            return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
+        } else {
+            return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes);
+        }
+    }
+
+    /**
+     * Get the complete SQL string formed by the current specifications of this QueryBuilder.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *     echo $qb->getSQL(); // SELECT u FROM User u
+     * </code>
+     *
+     * @return string The sql query string.
+     */
+    public function getSQL()
+    {
+        if ($this->sql !== null && $this->state === self::STATE_CLEAN) {
+            return $this->sql;
+        }
+
+        $sql = '';
+
+        switch ($this->type) {
+            case self::DELETE:
+                $sql = $this->getSQLForDelete();
+                break;
+
+            case self::UPDATE:
+                $sql = $this->getSQLForUpdate();
+                break;
+
+            case self::SELECT:
+            default:
+                $sql = $this->getSQLForSelect();
+                break;
+        }
+
+        $this->state = self::STATE_CLEAN;
+        $this->sql = $sql;
+
+        return $sql;
+    }
+
+    /**
+     * Sets a query parameter for the query being constructed.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('users', 'u')
+     *         ->where('u.id = :user_id')
+     *         ->setParameter(':user_id', 1);
+     * </code>
+     *
+     * @param string|integer $key The parameter position or name.
+     * @param mixed $value The parameter value.
+     * @param string|null $type PDO::PARAM_*
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setParameter($key, $value, $type = null)
+    {
+        if ($type !== null) {
+            $this->paramTypes[$key] = $type;
+        }
+
+        $this->params[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets a collection of query parameters for the query being constructed.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('users', 'u')
+     *         ->where('u.id = :user_id1 OR u.id = :user_id2')
+     *         ->setParameters(array(
+     *             ':user_id1' => 1,
+     *             ':user_id2' => 2
+     *         ));
+     * </code>
+     *
+     * @param array $params The query parameters to set.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setParameters(array $params, array $types = array())
+    {
+        $this->paramTypes = $types;
+        $this->params = $params;
+
+        return $this;
+    }
+
+    /**
+     * Gets all defined query parameters for the query being constructed.
+     *
+     * @return array The currently defined query parameters.
+     */
+    public function getParameters()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Gets a (previously set) query parameter of the query being constructed.
+     *
+     * @param mixed $key The key (index or name) of the bound parameter.
+     * @return mixed The value of the bound parameter.
+     */
+    public function getParameter($key)
+    {
+        return isset($this->params[$key]) ? $this->params[$key] : null;
+    }
+
+    /**
+     * Sets the position of the first result to retrieve (the "offset").
+     *
+     * @param integer $firstResult The first result to return.
+     * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
+     */
+    public function setFirstResult($firstResult)
+    {
+        $this->state = self::STATE_DIRTY;
+        $this->firstResult = $firstResult;
+        return $this;
+    }
+
+    /**
+     * Gets the position of the first result the query object was set to retrieve (the "offset").
+     * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
+     *
+     * @return integer The position of the first result.
+     */
+    public function getFirstResult()
+    {
+        return $this->firstResult;
+    }
+
+    /**
+     * Sets the maximum number of results to retrieve (the "limit").
+     *
+     * @param integer $maxResults The maximum number of results to retrieve.
+     * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
+     */
+    public function setMaxResults($maxResults)
+    {
+        $this->state = self::STATE_DIRTY;
+        $this->maxResults = $maxResults;
+        return $this;
+    }
+
+    /**
+     * Gets the maximum number of results the query object was set to retrieve (the "limit").
+     * Returns NULL if {@link setMaxResults} was not applied to this query builder.
+     *
+     * @return integer Maximum number of results.
+     */
+    public function getMaxResults()
+    {
+        return $this->maxResults;
+    }
+
+    /**
+     * Either appends to or replaces a single, generic query part.
+     *
+     * The available parts are: 'select', 'from', 'set', 'where',
+     * 'groupBy', 'having' and 'orderBy'.
+     *
+     * @param string $sqlPartName
+     * @param string $sqlPart
+     * @param string $append
+     * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
+     */
+    public function add($sqlPartName, $sqlPart, $append = false)
+    {
+        $isArray = is_array($sqlPart);
+        $isMultiple = is_array($this->sqlParts[$sqlPartName]);
+
+        if ($isMultiple && !$isArray) {
+            $sqlPart = array($sqlPart);
+        }
+
+        $this->state = self::STATE_DIRTY;
+
+        if ($append) {
+            if ($sqlPartName == "orderBy" || $sqlPartName == "groupBy" || $sqlPartName == "select" || $sqlPartName == "set") {
+                foreach ($sqlPart AS $part) {
+                    $this->sqlParts[$sqlPartName][] = $part;
+                }
+            } else if ($isArray && is_array($sqlPart[key($sqlPart)])) {
+                $key = key($sqlPart);
+                $this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key];
+            } else if ($isMultiple) {
+                $this->sqlParts[$sqlPartName][] = $sqlPart;
+            } else {
+                $this->sqlParts[$sqlPartName] = $sqlPart;
+            }
+
+            return $this;
+        }
+
+        $this->sqlParts[$sqlPartName] = $sqlPart;
+
+        return $this;
+    }
+
+    /**
+     * Specifies an item that is to be returned in the query result.
+     * Replaces any previously specified selections, if any.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.id', 'p.id')
+     *         ->from('users', 'u')
+     *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
+     * </code>
+     *
+     * @param mixed $select The selection expressions.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function select($select = null)
+    {
+        $this->type = self::SELECT;
+
+        if (empty($select)) {
+            return $this;
+        }
+
+        $selects = is_array($select) ? $select : func_get_args();
+
+        return $this->add('select', $selects, false);
+    }
+
+    /**
+     * Adds an item that is to be returned in the query result.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.id')
+     *         ->addSelect('p.id')
+     *         ->from('users', 'u')
+     *         ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
+     * </code>
+     *
+     * @param mixed $select The selection expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addSelect($select = null)
+    {
+        $this->type = self::SELECT;
+
+        if (empty($select)) {
+            return $this;
+        }
+
+        $selects = is_array($select) ? $select : func_get_args();
+
+        return $this->add('select', $selects, true);
+    }
+
+    /**
+     * Turns the query being built into a bulk delete query that ranges over
+     * a certain table.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->delete('users', 'u')
+     *         ->where('u.id = :user_id');
+     *         ->setParameter(':user_id', 1);
+     * </code>
+     *
+     * @param string $delete The table whose rows are subject to the deletion.
+     * @param string $alias The table alias used in the constructed query.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function delete($delete = null, $alias = null)
+    {
+        $this->type = self::DELETE;
+
+        if ( ! $delete) {
+            return $this;
+        }
+
+        return $this->add('from', array(
+            'table' => $delete,
+            'alias' => $alias
+        ));
+    }
+
+    /**
+     * Turns the query being built into a bulk update query that ranges over
+     * a certain table
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->update('users', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where('u.id = ?');
+     * </code>
+     *
+     * @param string $update The table whose rows are subject to the update.
+     * @param string $alias The table alias used in the constructed query.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function update($update = null, $alias = null)
+    {
+        $this->type = self::UPDATE;
+
+        if ( ! $update) {
+            return $this;
+        }
+
+        return $this->add('from', array(
+            'table' => $update,
+            'alias' => $alias
+        ));
+    }
+
+    /**
+     * Create and add a query root corresponding to the table identified by the
+     * given alias, forming a cartesian product with any existing query roots.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.id')
+     *         ->from('users', 'u')
+     * </code>
+     *
+     * @param string $from   The table
+     * @param string $alias  The alias of the table
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function from($from, $alias)
+    {
+        return $this->add('from', array(
+            'table' => $from,
+            'alias' => $alias
+        ), true);
+    }
+
+    /**
+     * Creates and adds a join to the query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $fromAlias The alias that points to a from clause
+     * @param string $join The table name to join
+     * @param string $alias The alias of the join table
+     * @param string $condition The condition for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function join($fromAlias, $join, $alias, $condition = null)
+    {
+        return $this->innerJoin($fromAlias, $join, $alias, $condition);
+    }
+
+    /**
+     * Creates and adds a join to the query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $fromAlias The alias that points to a from clause
+     * @param string $join The table name to join
+     * @param string $alias The alias of the join table
+     * @param string $condition The condition for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function innerJoin($fromAlias, $join, $alias, $condition = null)
+    {
+        return $this->add('join', array(
+            $fromAlias => array(
+                'joinType'      => 'inner',
+                'joinTable'     => $join,
+                'joinAlias'     => $alias,
+                'joinCondition' => $condition
+            )
+        ), true);
+    }
+
+    /**
+     * Creates and adds a left join to the query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $fromAlias The alias that points to a from clause
+     * @param string $join The table name to join
+     * @param string $alias The alias of the join table
+     * @param string $condition The condition for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function leftJoin($fromAlias, $join, $alias, $condition = null)
+    {
+        return $this->add('join', array(
+            $fromAlias => array(
+                'joinType'      => 'left',
+                'joinTable'     => $join,
+                'joinAlias'     => $alias,
+                'joinCondition' => $condition
+            )
+        ), true);
+    }
+
+    /**
+     * Creates and adds a right join to the query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $fromAlias The alias that points to a from clause
+     * @param string $join The table name to join
+     * @param string $alias The alias of the join table
+     * @param string $condition The condition for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function rightJoin($fromAlias, $join, $alias, $condition = null)
+    {
+        return $this->add('join', array(
+            $fromAlias => array(
+                'joinType'      => 'right',
+                'joinTable'     => $join,
+                'joinAlias'     => $alias,
+                'joinCondition' => $condition
+            )
+        ), true);
+    }
+
+    /**
+     * Sets a new value for a column in a bulk update query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->update('users', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where('u.id = ?');
+     * </code>
+     *
+     * @param string $key The column to set.
+     * @param string $value The value, expression, placeholder, etc.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function set($key, $value)
+    {
+        return $this->add('set', $key .' = ' . $value, true);
+    }
+
+    /**
+     * Specifies one or more restrictions to the query result.
+     * Replaces any previously specified restrictions, if any.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->where('u.id = ?');
+     *
+     *     // You can optionally programatically build and/or expressions
+     *     $qb = $conn->createQueryBuilder();
+     *
+     *     $or = $qb->expr()->orx();
+     *     $or->add($qb->expr()->eq('u.id', 1));
+     *     $or->add($qb->expr()->eq('u.id', 2));
+     *
+     *     $qb->update('users', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where($or);
+     * </code>
+     *
+     * @param mixed $predicates The restriction predicates.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function where($predicates)
+    {
+        if ( ! (func_num_args() == 1 && $predicates instanceof CompositeExpression) ) {
+            $predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
+        }
+
+        return $this->add('where', $predicates);
+    }
+
+    /**
+     * Adds one or more restrictions to the query results, forming a logical
+     * conjunction with any previously specified restrictions.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('users', 'u')
+     *         ->where('u.username LIKE ?')
+     *         ->andWhere('u.is_active = 1');
+     * </code>
+     *
+     * @param mixed $where The query restrictions.
+     * @return QueryBuilder This QueryBuilder instance.
+     * @see where()
+     */
+    public function andWhere($where)
+    {
+        $where = $this->getQueryPart('where');
+        $args = func_get_args();
+
+        if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) {
+            $where->addMultiple($args);
+        } else {
+            array_unshift($args, $where);
+            $where = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
+        }
+
+        return $this->add('where', $where, true);
+    }
+
+    /**
+     * Adds one or more restrictions to the query results, forming a logical
+     * disjunction with any previously specified restrictions.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->where('u.id = 1')
+     *         ->orWhere('u.id = 2');
+     * </code>
+     *
+     * @param mixed $where The WHERE statement
+     * @return QueryBuilder $qb
+     * @see where()
+     */
+    public function orWhere($where)
+    {
+        $where = $this->getQueryPart('where');
+        $args = func_get_args();
+
+        if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) {
+            $where->addMultiple($args);
+        } else {
+            array_unshift($args, $where);
+            $where = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
+        }
+
+        return $this->add('where', $where, true);
+    }
+
+    /**
+     * Specifies a grouping over the results of the query.
+     * Replaces any previously specified groupings, if any.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->groupBy('u.id');
+     * </code>
+     *
+     * @param mixed $groupBy The grouping expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function groupBy($groupBy)
+    {
+        if (empty($groupBy)) {
+            return $this;
+        }
+
+        $groupBy = is_array($groupBy) ? $groupBy : func_get_args();
+
+        return $this->add('groupBy', $groupBy, false);
+    }
+
+
+    /**
+     * Adds a grouping expression to the query.
+     *
+     * <code>
+     *     $qb = $conn->createQueryBuilder()
+     *         ->select('u.name')
+     *         ->from('users', 'u')
+     *         ->groupBy('u.lastLogin');
+     *         ->addGroupBy('u.createdAt')
+     * </code>
+     *
+     * @param mixed $groupBy The grouping expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addGroupBy($groupBy)
+    {
+        if (empty($groupBy)) {
+            return $this;
+        }
+
+        $groupBy = is_array($groupBy) ? $groupBy : func_get_args();
+
+        return $this->add('groupBy', $groupBy, true);
+    }
+
+    /**
+     * Specifies a restriction over the groups of the query.
+     * Replaces any previous having restrictions, if any.
+     *
+     * @param mixed $having The restriction over the groups.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function having($having)
+    {
+        if ( ! (func_num_args() == 1 && $having instanceof CompositeExpression)) {
+            $having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Adds a restriction over the groups of the query, forming a logical
+     * conjunction with any existing having restrictions.
+     *
+     * @param mixed $having The restriction to append.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function andHaving($having)
+    {
+        $having = $this->getQueryPart('having');
+        $args = func_get_args();
+
+        if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) {
+            $having->addMultiple($args);
+        } else {
+            array_unshift($args, $having);
+            $having = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Adds a restriction over the groups of the query, forming a logical
+     * disjunction with any existing having restrictions.
+     *
+     * @param mixed $having The restriction to add.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function orHaving($having)
+    {
+        $having = $this->getQueryPart('having');
+        $args = func_get_args();
+
+        if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) {
+            $having->addMultiple($args);
+        } else {
+            array_unshift($args, $having);
+            $having = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Specifies an ordering for the query results.
+     * Replaces any previously specified orderings, if any.
+     *
+     * @param string $sort The ordering expression.
+     * @param string $order The ordering direction.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function orderBy($sort, $order = null)
+    {
+        return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), false);
+    }
+
+    /**
+     * Adds an ordering to the query results.
+     *
+     * @param string $sort The ordering expression.
+     * @param string $order The ordering direction.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addOrderBy($sort, $order = null)
+    {
+        return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), true);
+    }
+
+    /**
+     * Get a query part by its name.
+     *
+     * @param string $queryPartName
+     * @return mixed $queryPart
+     */
+    public function getQueryPart($queryPartName)
+    {
+        return $this->sqlParts[$queryPartName];
+    }
+
+    /**
+     * Get all query parts.
+     *
+     * @return array $sqlParts
+     */
+    public function getQueryParts()
+    {
+        return $this->sqlParts;
+    }
+
+    /**
+     * Reset SQL parts
+     *
+     * @param array $queryPartNames
+     * @return QueryBuilder
+     */
+    public function resetQueryParts($queryPartNames = null)
+    {
+        if (is_null($queryPartNames)) {
+            $queryPartNames = array_keys($this->sqlParts);
+        }
+
+        foreach ($queryPartNames as $queryPartName) {
+            $this->resetQueryPart($queryPartName);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Reset single SQL part
+     *
+     * @param string $queryPartName
+     * @return QueryBuilder
+     */
+    public function resetQueryPart($queryPartName)
+    {
+        $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName])
+            ? array() : null;
+
+        $this->state = self::STATE_DIRTY;
+
+        return $this;
+    }
+
+    /**
+     * Converts this instance into a SELECT string in SQL.
+     *
+     * @return string
+     */
+    private function getSQLForSelect()
+    {
+        $query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM ';
+
+        $fromClauses = array();
+
+        // Loop through all FROM clauses
+        foreach ($this->sqlParts['from'] as $from) {
+            $fromClause = $from['table'] . ' ' . $from['alias'];
+
+            if (isset($this->sqlParts['join'][$from['alias']])) {
+                foreach ($this->sqlParts['join'][$from['alias']] as $join) {
+                    $fromClause .= ' ' . strtoupper($join['joinType'])
+                                 . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
+                                 . ' ON ' . ((string) $join['joinCondition']);
+                }
+            }
+
+            $fromClauses[$from['alias']] = $fromClause;
+        }
+
+        // loop through all JOIN clasues for validation purpose
+        foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
+            if ( ! isset($fromClauses[$fromAlias]) ) {
+                throw QueryException::unknownFromAlias($fromAlias, array_keys($fromClauses));
+            }
+        }
+
+        $query .= implode(', ', $fromClauses)
+                . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
+                . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '')
+                . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '')
+                . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : '');
+
+        return ($this->maxResults === null && $this->firstResult == null)
+            ? $query
+            : $this->connection->getDatabasePlatform()->modifyLimitQuery($query, $this->maxResults, $this->firstResult);
+    }
+
+    /**
+     * Converts this instance into an UPDATE string in SQL.
+     *
+     * @return string
+     */
+    private function getSQLForUpdate()
+    {
+        $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
+        $query = 'UPDATE ' . $table
+               . ' SET ' . implode(", ", $this->sqlParts['set'])
+               . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
+
+        return $query;
+    }
+
+    /**
+     * Converts this instance into a DELETE string in SQL.
+     *
+     * @return string
+     */
+    private function getSQLForDelete()
+    {
+        $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
+        $query = 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
+
+        return $query;
+    }
+
+    /**
+     * Gets a string representation of this QueryBuilder which corresponds to
+     * the final SQL query being constructed.
+     *
+     * @return string The string representation of this QueryBuilder.
+     */
+    public function __toString()
+    {
+        return $this->getSQL();
+    }
+
+    /**
+     * Create a new named parameter and bind the value $value to it.
+     *
+     * This method provides a shortcut for PDOStatement::bindValue
+     * when using prepared statements.
+     *
+     * The parameter $value specifies the value that you want to bind. If
+     * $placeholder is not provided bindValue() will automatically create a
+     * placeholder for you. An automatic placeholder will be of the name
+     * ':dcValue1', ':dcValue2' etc.
+     *
+     * For more information see {@link http://php.net/pdostatement-bindparam}
+     *
+     * Example:
+     * <code>
+     * $value = 2;
+     * $q->eq( 'id', $q->bindValue( $value ) );
+     * $stmt = $q->executeQuery(); // executed with 'id = 2'
+     * </code>
+     *
+     * @license New BSD License
+     * @link http://www.zetacomponents.org
+     * @param mixed $value
+     * @param mixed $type
+     * @param string $placeHolder the name to bind with. The string must start with a colon ':'.
+     * @return string the placeholder name used.
+     */
+    public function createNamedParameter( $value, $type = \PDO::PARAM_STR, $placeHolder = null )
+    {
+        if ( $placeHolder === null ) {
+            $this->boundCounter++;
+            $placeHolder = ":dcValue" . $this->boundCounter;
+        }
+        $this->setParameter(substr($placeHolder, 1), $value, $type);
+
+        return $placeHolder;
+    }
+
+    /**
+     * Create a new positional parameter and bind the given value to it.
+     *
+     * Attention: If you are using positional parameters with the query builder you have
+     * to be very careful to bind all parameters in the order they appear in the SQL
+     * statement , otherwise they get bound in the wrong order which can lead to serious
+     * bugs in your code.
+     *
+     * Example:
+     * <code>
+     *  $qb = $conn->createQueryBuilder();
+     *  $qb->select('u.*')
+     *     ->from('users', 'u')
+     *     ->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR))
+     *     ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR))
+     * </code>
+     *
+     * @param  mixed $value
+     * @param  mixed $type
+     * @return string
+     */
+    public function createPositionalParameter($value, $type = \PDO::PARAM_STR)
+    {
+        $this->boundCounter++;
+        $this->setParameter($this->boundCounter, $value, $type);
+        return "?";
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Query/QueryException.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Query;
+
+use Doctrine\DBAL\DBALException;
+
+/**
+ * Driver interface.
+ * Interface that all DBAL drivers must implement.
+ *
+ * @since 2.1.4
+ */
+class QueryException extends DBALException
+{
+    static public function unknownFromAlias($alias, $registeredAliases)
+    {
+        return new self("The given alias '" . $alias . "' is not part of " .
+            "any FROM clause table. The currently registered FROM-clause " .
+            "aliases are: " . implode(", ", $registeredAliases) . ". Join clauses " .
+            "are bound to from clauses to provide support for mixing of multiple " .
+            "from and join clauses.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/SQLParserUtils.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/SQLParserUtils.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/SQLParserUtils.php	(revision 345)
@@ -0,0 +1,179 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * Utility class that parses sql statements with regard to types and parameters.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SQLParserUtils
+{
+    /**
+     * Get an array of the placeholders in an sql statements as keys and their positions in the query string.
+     *
+     * Returns an integer => integer pair (indexed from zero) for a positional statement
+     * and a string => int[] pair for a named statement.
+     *
+     * @param string $statement
+     * @param bool $isPositional
+     * @return array
+     */
+    static public function getPlaceholderPositions($statement, $isPositional = true)
+    {
+        $match = ($isPositional) ? '?' : ':';
+        if (strpos($statement, $match) === false) {
+            return array();
+        }
+
+        $count = 0;
+        $inLiteral = false; // a valid query never starts with quotes
+        $stmtLen = strlen($statement);
+        $paramMap = array();
+        for ($i = 0; $i < $stmtLen; $i++) {
+            if ($statement[$i] == $match && !$inLiteral) {
+                // real positional parameter detected
+                if ($isPositional) {
+                    $paramMap[$count] = $i;
+                } else {
+                    $name = "";
+                    // TODO: Something faster/better to match this than regex?
+                    for ($j = $i; ($j < $stmtLen && preg_match('(([:a-zA-Z0-9_]{1}))', $statement[$j])); $j++) {
+                        $name .= $statement[$j];
+                    }
+                    $paramMap[$name][] = $i; // named parameters can be duplicated!
+                    $i = $j;
+                }
+                ++$count;
+            } else if ($statement[$i] == "'" || $statement[$i] == '"') {
+                $inLiteral = ! $inLiteral; // switch state!
+            }
+        }
+
+        return $paramMap;
+    }
+
+    /**
+     * For a positional query this method can rewrite the sql statement with regard to array parameters.
+     *
+     * @param string $query
+     * @param array $params
+     * @param array $types
+     */
+    static public function expandListParameters($query, $params, $types)
+    {
+        $isPositional = is_int(key($params));
+        $arrayPositions = array();
+        $bindIndex = -1;
+        foreach ($types AS $name => $type) {
+            ++$bindIndex;
+            if ($type === Connection::PARAM_INT_ARRAY || $type === Connection::PARAM_STR_ARRAY) {
+                if ($isPositional) {
+                    $name = $bindIndex;
+                }
+
+                $arrayPositions[$name] = false;
+            }
+        }
+
+        if ((!$arrayPositions && $isPositional) || (count($params) != count($types))) {
+            return array($query, $params, $types);
+        }
+
+        $paramPos = self::getPlaceholderPositions($query, $isPositional);
+        if ($isPositional) {
+            $paramOffset = 0;
+            $queryOffset = 0;
+            foreach ($paramPos AS $needle => $needlePos) {
+                if (!isset($arrayPositions[$needle])) {
+                    continue;
+                }
+
+                $needle += $paramOffset;
+                $needlePos += $queryOffset;
+                $len = count($params[$needle]);
+
+                $params = array_merge(
+                    array_slice($params, 0, $needle),
+                    $params[$needle],
+                    array_slice($params, $needle + 1)
+                );
+
+                $types = array_merge(
+                    array_slice($types, 0, $needle),
+                    array_fill(0, $len, $types[$needle] - Connection::ARRAY_PARAM_OFFSET), // array needles are at PDO::PARAM_* + 100
+                    array_slice($types, $needle + 1)
+                );
+
+                $expandStr = implode(", ", array_fill(0, $len, "?"));
+                $query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1);
+
+                $paramOffset += ($len - 1); // Grows larger by number of parameters minus the replaced needle.
+                $queryOffset += (strlen($expandStr) - 1);
+            }
+
+        } else {
+            $queryOffset= 0;
+            $typesOrd   = array();
+            $paramsOrd  = array();
+            foreach ($paramPos as $needle => $needlePos) {
+                $paramLen   = strlen($needle);
+                $token      = substr($needle,0,1);
+                $needle     = substr($needle,1);
+                $value      = $params[$needle];
+
+                if (!isset($arrayPositions[$needle])) {
+                    foreach ($needlePos as $pos) {
+                        $pos         += $queryOffset;
+                        $queryOffset -= ($paramLen - 1);
+                        $paramsOrd[]  = $value;
+                        $typesOrd[]   = $types[$needle];
+                        $query        = substr($query, 0, $pos) . '?' . substr($query, ($pos + $paramLen));
+                    }
+                } else {
+                    $len = count($value);
+                    $expandStr = implode(", ", array_fill(0, $len, "?"));
+                    foreach ($needlePos as $pos) {
+
+                        foreach ($value as $val) {
+                            $paramsOrd[] = $val;
+                            $typesOrd[]  = $types[$needle] - Connection::ARRAY_PARAM_OFFSET;
+                        }
+
+                        $pos         += $queryOffset;
+                        $queryOffset += (strlen($expandStr) - $paramLen);
+                        $query        = substr($query, 0, $pos) . $expandStr . substr($query, ($pos + $paramLen));
+                    }
+                }
+            }
+
+            $types  = $typesOrd;
+            $params = $paramsOrd;
+        }
+
+        return array($query, $params, $types);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractAsset.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractAsset.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractAsset.php	(revision 345)
@@ -0,0 +1,204 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * The abstract asset allows to reset the name of all assets without publishing this to the public userland.
+ *
+ * This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
+ * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class AbstractAsset
+{
+    /**
+     * @var string
+     */
+    protected $_name;
+
+    /**
+     * Namespace of the asset. If none isset the default namespace is assumed.
+     *
+     * @var string
+     */
+    protected $_namespace;
+
+    /**
+     * @var bool
+     */
+    protected $_quoted = false;
+
+    /**
+     * Set name of this asset
+     *
+     * @param string $name
+     */
+    protected function _setName($name)
+    {
+        if ($this->isQuoted($name)) {
+            $this->_quoted = true;
+            $name = $this->trimQuotes($name);
+        }
+        if (strpos($name, ".") !== false) {
+            $parts = explode(".", $name);
+            $this->_namespace = $parts[0];
+            $name = $parts[1];
+        }
+        $this->_name = $name;
+    }
+
+    /**
+     * Is this asset in the default namespace?
+     *
+     * @param string $defaultNamespaceName
+     * @return bool
+     */
+    public function isInDefaultNamespace($defaultNamespaceName)
+    {
+        return $this->_namespace == $defaultNamespaceName || $this->_namespace === null;
+    }
+
+    /**
+     * Get namespace name of this asset.
+     *
+     * If NULL is returned this means the default namespace is used.
+     *
+     * @return string
+     */
+    public function getNamespaceName()
+    {
+        return $this->_namespace;
+    }
+
+    /**
+     * The shortest name is stripped of the default namespace. All other
+     * namespaced elements are returned as full-qualified names.
+     *
+     * @param string
+     * @return string
+     */
+    public function getShortestName($defaultNamespaceName)
+    {
+        $shortestName = $this->getName();
+        if ($this->_namespace == $defaultNamespaceName) {
+            $shortestName = $this->_name;
+        }
+        return strtolower($shortestName);
+    }
+
+    /**
+     * The normalized name is full-qualified and lowerspaced. Lowerspacing is
+     * actually wrong, but we have to do it to keep our sanity. If you are
+     * using database objects that only differentiate in the casing (FOO vs
+     * Foo) then you will NOT be able to use Doctrine Schema abstraction.
+     *
+     * Every non-namespaced element is prefixed with the default namespace
+     * name which is passed as argument to this method.
+     *
+     * @return string
+     */
+    public function getFullQualifiedName($defaultNamespaceName)
+    {
+        $name = $this->getName();
+        if (!$this->_namespace) {
+            $name = $defaultNamespaceName . "." . $name;
+        }
+        return strtolower($name);
+    }
+
+    /**
+     * Check if this identifier is quoted.
+     *
+     * @param  string $identifier
+     * @return bool
+     */
+    protected function isQuoted($identifier)
+    {
+        return (isset($identifier[0]) && ($identifier[0] == '`' || $identifier[0] == '"'));
+    }
+
+    /**
+     * Trim quotes from the identifier.
+     *
+     * @param  string $identifier
+     * @return string
+     */
+    protected function trimQuotes($identifier)
+    {
+        return str_replace(array('`', '"'), '', $identifier);
+    }
+
+    /**
+     * Return name of this schema asset.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        if ($this->_namespace) {
+            return $this->_namespace . "." . $this->_name;
+        }
+        return $this->_name;
+    }
+
+    /**
+     * Get the quoted representation of this asset but only if it was defined with one. Otherwise
+     * return the plain unquoted value as inserted.
+     *
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function getQuotedName(AbstractPlatform $platform)
+    {
+        $keywords = $platform->getReservedKeywordsList();
+        $parts = explode(".", $this->getName());
+        foreach ($parts AS $k => $v) {
+            $parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
+        }
+
+        return implode(".", $parts);
+    }
+
+    /**
+     * Generate an identifier from a list of column names obeying a certain string length.
+     *
+     * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
+     * however building idents automatically for foreign keys, composite keys or such can easily create
+     * very long names.
+     *
+     * @param  array $columnNames
+     * @param  string $prefix
+     * @param  int $maxSize
+     * @return string
+     */
+    protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30)
+    {
+        $hash = implode("", array_map(function($column) {
+            return dechex(crc32($column));
+        }, $columnNames));
+        return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/AbstractSchemaManager.php	(revision 345)
@@ -0,0 +1,890 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Events;
+use Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs;
+use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
+use Doctrine\DBAL\Types;
+use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Base class for schema managers. Schema managers are used to inspect and/or
+ * modify the database schema/structure.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @since       2.0
+ */
+abstract class AbstractSchemaManager
+{
+    /**
+     * Holds instance of the Doctrine connection for this schema manager
+     *
+     * @var \Doctrine\DBAL\Connection
+     */
+    protected $_conn;
+
+    /**
+     * Holds instance of the database platform used for this schema manager
+     *
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    protected $_platform;
+
+    /**
+     * Constructor. Accepts the Connection instance to manage the schema for
+     *
+     * @param \Doctrine\DBAL\Connection $conn
+     */
+    public function __construct(\Doctrine\DBAL\Connection $conn)
+    {
+        $this->_conn = $conn;
+        $this->_platform = $this->_conn->getDatabasePlatform();
+    }
+
+    /**
+     * Return associated platform.
+     *
+     * @return \Doctrine\DBAL\Platform\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * Try any method on the schema manager. Normally a method throws an
+     * exception when your DBMS doesn't support it or if an error occurs.
+     * This method allows you to try and method on your SchemaManager
+     * instance and will return false if it does not work or is not supported.
+     *
+     * <code>
+     * $result = $sm->tryMethod('dropView', 'view_name');
+     * </code>
+     *
+     * @return mixed
+     */
+    public function tryMethod()
+    {
+        $args = func_get_args();
+        $method = $args[0];
+        unset($args[0]);
+        $args = array_values($args);
+
+        try {
+            return call_user_func_array(array($this, $method), $args);
+        } catch (\Exception $e) {
+            return false;
+        }
+    }
+
+    /**
+     * List the available databases for this connection
+     *
+     * @return array $databases
+     */
+    public function listDatabases()
+    {
+        $sql = $this->_platform->getListDatabasesSQL();
+
+        $databases = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableDatabasesList($databases);
+    }
+
+    /**
+     * List the available sequences for this connection
+     *
+     * @return Sequence[]
+     */
+    public function listSequences($database = null)
+    {
+        if (is_null($database)) {
+            $database = $this->_conn->getDatabase();
+        }
+        $sql = $this->_platform->getListSequencesSQL($database);
+
+        $sequences = $this->_conn->fetchAll($sql);
+
+        return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
+    }
+
+    /**
+     * List the columns for a given table.
+     *
+     * In contrast to other libraries and to the old version of Doctrine,
+     * this column definition does try to contain the 'primary' field for
+     * the reason that it is not portable accross different RDBMS. Use
+     * {@see listTableIndexes($tableName)} to retrieve the primary key
+     * of a table. We're a RDBMS specifies more details these are held
+     * in the platformDetails array.
+     *
+     * @param string $table The name of the table.
+     * @param string $database
+     * @return Column[]
+     */
+    public function listTableColumns($table, $database = null)
+    {
+        if (!$database) {
+            $database = $this->_conn->getDatabase();
+        }
+
+        $sql = $this->_platform->getListTableColumnsSQL($table, $database);
+
+        $tableColumns = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableTableColumnList($table, $database, $tableColumns);
+    }
+
+    /**
+     * List the indexes for a given table returning an array of Index instances.
+     *
+     * Keys of the portable indexes list are all lower-cased.
+     *
+     * @param string $table The name of the table
+     * @return Index[] $tableIndexes
+     */
+    public function listTableIndexes($table)
+    {
+        $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
+
+        $tableIndexes = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableTableIndexesList($tableIndexes, $table);
+    }
+
+    /**
+     * Return true if all the given tables exist.
+     *
+     * @param array $tableNames
+     * @return bool
+     */
+    public function tablesExist($tableNames)
+    {
+        $tableNames = array_map('strtolower', (array)$tableNames);
+        return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames())));
+    }
+
+    /**
+     * Return a list of all tables in the current database
+     *
+     * @return array
+     */
+    public function listTableNames()
+    {
+        $sql = $this->_platform->getListTablesSQL();
+
+        $tables = $this->_conn->fetchAll($sql);
+        $tableNames = $this->_getPortableTablesList($tables);
+        return $this->filterAssetNames($tableNames);
+    }
+
+    /**
+     * Filter asset names if they are configured to return only a subset of all
+     * the found elements.
+     *
+     * @param array $assetNames
+     * @return array
+     */
+    protected function filterAssetNames($assetNames)
+    {
+        $filterExpr = $this->getFilterSchemaAssetsExpression();
+        if (!$filterExpr) {
+            return $assetNames;
+        }
+        return array_values (
+            array_filter($assetNames, function ($assetName) use ($filterExpr) {
+                $assetName = ($assetName instanceof AbstractAsset) ? $assetName->getName() : $assetName;
+                return preg_match('(' . $filterExpr . ')', $assetName);
+            })
+        );
+    }
+
+    protected function getFilterSchemaAssetsExpression()
+    {
+        return $this->_conn->getConfiguration()->getFilterSchemaAssetsExpression();
+    }
+
+    /**
+     * List the tables for this connection
+     *
+     * @return Table[]
+     */
+    public function listTables()
+    {
+        $tableNames = $this->listTableNames();
+
+        $tables = array();
+        foreach ($tableNames AS $tableName) {
+            $tables[] = $this->listTableDetails($tableName);
+        }
+
+        return $tables;
+    }
+
+    /**
+     * @param  string $tableName
+     * @return Table
+     */
+    public function listTableDetails($tableName)
+    {
+        $columns = $this->listTableColumns($tableName);
+        $foreignKeys = array();
+        if ($this->_platform->supportsForeignKeyConstraints()) {
+            $foreignKeys = $this->listTableForeignKeys($tableName);
+        }
+        $indexes = $this->listTableIndexes($tableName);
+
+        return new Table($tableName, $columns, $indexes, $foreignKeys, false, array());
+    }
+
+    /**
+     * List the views this connection has
+     *
+     * @return View[]
+     */
+    public function listViews()
+    {
+        $database = $this->_conn->getDatabase();
+        $sql = $this->_platform->getListViewsSQL($database);
+        $views = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableViewsList($views);
+    }
+
+    /**
+     * List the foreign keys for the given table
+     *
+     * @param string $table  The name of the table
+     * @return ForeignKeyConstraint[]
+     */
+    public function listTableForeignKeys($table, $database = null)
+    {
+        if (is_null($database)) {
+            $database = $this->_conn->getDatabase();
+        }
+        $sql = $this->_platform->getListTableForeignKeysSQL($table, $database);
+        $tableForeignKeys = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableTableForeignKeysList($tableForeignKeys);
+    }
+
+    /* drop*() Methods */
+
+    /**
+     * Drops a database.
+     *
+     * NOTE: You can not drop the database this SchemaManager is currently connected to.
+     *
+     * @param string $database The name of the database to drop
+     */
+    public function dropDatabase($database)
+    {
+        $this->_execSql($this->_platform->getDropDatabaseSQL($database));
+    }
+
+    /**
+     * Drop the given table
+     *
+     * @param string $table The name of the table to drop
+     */
+    public function dropTable($table)
+    {
+        $this->_execSql($this->_platform->getDropTableSQL($table));
+    }
+
+    /**
+     * Drop the index from the given table
+     *
+     * @param Index|string $index  The name of the index
+     * @param string|Table $table The name of the table
+     */
+    public function dropIndex($index, $table)
+    {
+        if($index instanceof Index) {
+            $index = $index->getQuotedName($this->_platform);
+        }
+
+        $this->_execSql($this->_platform->getDropIndexSQL($index, $table));
+    }
+
+    /**
+     * Drop the constraint from the given table
+     *
+     * @param Constraint $constraint
+     * @param string $table   The name of the table
+     */
+    public function dropConstraint(Constraint $constraint, $table)
+    {
+        $this->_execSql($this->_platform->getDropConstraintSQL($constraint, $table));
+    }
+
+    /**
+     * Drops a foreign key from a table.
+     *
+     * @param ForeignKeyConstraint|string $table The name of the table with the foreign key.
+     * @param Table|string $name  The name of the foreign key.
+     * @return boolean $result
+     */
+    public function dropForeignKey($foreignKey, $table)
+    {
+        $this->_execSql($this->_platform->getDropForeignKeySQL($foreignKey, $table));
+    }
+
+    /**
+     * Drops a sequence with a given name.
+     *
+     * @param string $name The name of the sequence to drop.
+     */
+    public function dropSequence($name)
+    {
+        $this->_execSql($this->_platform->getDropSequenceSQL($name));
+    }
+
+    /**
+     * Drop a view
+     *
+     * @param string $name The name of the view
+     * @return boolean $result
+     */
+    public function dropView($name)
+    {
+        $this->_execSql($this->_platform->getDropViewSQL($name));
+    }
+
+    /* create*() Methods */
+
+    /**
+     * Creates a new database.
+     *
+     * @param string $database The name of the database to create.
+     */
+    public function createDatabase($database)
+    {
+        $this->_execSql($this->_platform->getCreateDatabaseSQL($database));
+    }
+
+    /**
+     * Create a new table.
+     *
+     * @param Table $table
+     * @param int $createFlags
+     */
+    public function createTable(Table $table)
+    {
+        $createFlags = AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS;
+        $this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags));
+    }
+
+    /**
+     * Create a new sequence
+     *
+     * @param Sequence $sequence
+     * @throws Doctrine\DBAL\ConnectionException     if something fails at database level
+     */
+    public function createSequence($sequence)
+    {
+        $this->_execSql($this->_platform->getCreateSequenceSQL($sequence));
+    }
+
+    /**
+     * Create a constraint on a table
+     *
+     * @param Constraint $constraint
+     * @param string|Table $table
+     */
+    public function createConstraint(Constraint $constraint, $table)
+    {
+        $this->_execSql($this->_platform->getCreateConstraintSQL($constraint, $table));
+    }
+
+    /**
+     * Create a new index on a table
+     *
+     * @param Index     $index
+     * @param string    $table         name of the table on which the index is to be created
+     */
+    public function createIndex(Index $index, $table)
+    {
+        $this->_execSql($this->_platform->getCreateIndexSQL($index, $table));
+    }
+
+    /**
+     * Create a new foreign key
+     *
+     * @param ForeignKeyConstraint  $foreignKey    ForeignKey instance
+     * @param string|Table          $table         name of the table on which the foreign key is to be created
+     */
+    public function createForeignKey(ForeignKeyConstraint $foreignKey, $table)
+    {
+        $this->_execSql($this->_platform->getCreateForeignKeySQL($foreignKey, $table));
+    }
+
+    /**
+     * Create a new view
+     *
+     * @param View $view
+     */
+    public function createView(View $view)
+    {
+        $this->_execSql($this->_platform->getCreateViewSQL($view->getQuotedName($this->_platform), $view->getSql()));
+    }
+
+    /* dropAndCreate*() Methods */
+
+    /**
+     * Drop and create a constraint
+     *
+     * @param Constraint    $constraint
+     * @param string        $table
+     * @see dropConstraint()
+     * @see createConstraint()
+     */
+    public function dropAndCreateConstraint(Constraint $constraint, $table)
+    {
+        $this->tryMethod('dropConstraint', $constraint, $table);
+        $this->createConstraint($constraint, $table);
+    }
+
+    /**
+     * Drop and create a new index on a table
+     *
+     * @param string|Table $table         name of the table on which the index is to be created
+     * @param Index $index
+     */
+    public function dropAndCreateIndex(Index $index, $table)
+    {
+        $this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table);
+        $this->createIndex($index, $table);
+    }
+
+    /**
+     * Drop and create a new foreign key
+     *
+     * @param ForeignKeyConstraint  $foreignKey    associative array that defines properties of the foreign key to be created.
+     * @param string|Table          $table         name of the table on which the foreign key is to be created
+     */
+    public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
+    {
+        $this->tryMethod('dropForeignKey', $foreignKey, $table);
+        $this->createForeignKey($foreignKey, $table);
+    }
+
+    /**
+     * Drop and create a new sequence
+     *
+     * @param Sequence $sequence
+     * @throws Doctrine\DBAL\ConnectionException     if something fails at database level
+     */
+    public function dropAndCreateSequence(Sequence $sequence)
+    {
+        $this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform));
+        $this->createSequence($sequence);
+    }
+
+    /**
+     * Drop and create a new table.
+     *
+     * @param Table $table
+     */
+    public function dropAndCreateTable(Table $table)
+    {
+        $this->tryMethod('dropTable', $table->getQuotedName($this->_platform));
+        $this->createTable($table);
+    }
+
+    /**
+     * Drop and creates a new database.
+     *
+     * @param string $database The name of the database to create.
+     */
+    public function dropAndCreateDatabase($database)
+    {
+        $this->tryMethod('dropDatabase', $database);
+        $this->createDatabase($database);
+    }
+
+    /**
+     * Drop and create a new view
+     *
+     * @param View $view
+     */
+    public function dropAndCreateView(View $view)
+    {
+        $this->tryMethod('dropView', $view->getQuotedName($this->_platform));
+        $this->createView($view);
+    }
+
+    /* alterTable() Methods */
+
+    /**
+     * Alter an existing tables schema
+     *
+     * @param TableDiff $tableDiff
+     */
+    public function alterTable(TableDiff $tableDiff)
+    {
+        $queries = $this->_platform->getAlterTableSQL($tableDiff);
+        if (is_array($queries) && count($queries)) {
+            foreach ($queries AS $ddlQuery) {
+                $this->_execSql($ddlQuery);
+            }
+        }
+    }
+
+    /**
+     * Rename a given table to another name
+     *
+     * @param string $name     The current name of the table
+     * @param string $newName  The new name of the table
+     */
+    public function renameTable($name, $newName)
+    {
+        $tableDiff = new TableDiff($name);
+        $tableDiff->newName = $newName;
+        $this->alterTable($tableDiff);
+    }
+
+    /**
+     * Methods for filtering return values of list*() methods to convert
+     * the native DBMS data definition to a portable Doctrine definition
+     */
+
+    protected function _getPortableDatabasesList($databases)
+    {
+        $list = array();
+        foreach ($databases as $key => $value) {
+            if ($value = $this->_getPortableDatabaseDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableDatabaseDefinition($database)
+    {
+        return $database;
+    }
+
+    protected function _getPortableFunctionsList($functions)
+    {
+        $list = array();
+        foreach ($functions as $key => $value) {
+            if ($value = $this->_getPortableFunctionDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableFunctionDefinition($function)
+    {
+        return $function;
+    }
+
+    protected function _getPortableTriggersList($triggers)
+    {
+        $list = array();
+        foreach ($triggers as $key => $value) {
+            if ($value = $this->_getPortableTriggerDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableTriggerDefinition($trigger)
+    {
+        return $trigger;
+    }
+
+    protected function _getPortableSequencesList($sequences)
+    {
+        $list = array();
+        foreach ($sequences as $key => $value) {
+            if ($value = $this->_getPortableSequenceDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    /**
+     * @param array $sequence
+     * @return Sequence
+     */
+    protected function _getPortableSequenceDefinition($sequence)
+    {
+        throw DBALException::notSupported('Sequences');
+    }
+
+    /**
+     * Independent of the database the keys of the column list result are lowercased.
+     *
+     * The name of the created column instance however is kept in its case.
+     *
+     * @param  string $table The name of the table.
+     * @param  string $database
+     * @param  array  $tableColumns
+     * @return array
+     */
+    protected function _getPortableTableColumnList($table, $database, $tableColumns)
+    {
+        $eventManager = $this->_platform->getEventManager();
+
+        $list = array();
+        foreach ($tableColumns as $key => $tableColumn) {
+            $column = null;
+            $defaultPrevented = false;
+
+            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) {
+                $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn, $table, $database, $this->_conn);
+                $eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs);
+
+                $defaultPrevented = $eventArgs->isDefaultPrevented();
+                $column = $eventArgs->getColumn();
+            }
+
+            if (!$defaultPrevented) {
+                $column = $this->_getPortableTableColumnDefinition($tableColumn);
+            }
+
+            if ($column) {
+                $name = strtolower($column->getQuotedName($this->_platform));
+                $list[$name] = $column;
+            }
+        }
+        return $list;
+    }
+
+    /**
+     * Get Table Column Definition
+     *
+     * @param array $tableColumn
+     * @return Column
+     */
+    abstract protected function _getPortableTableColumnDefinition($tableColumn);
+
+    /**
+     * Aggregate and group the index results according to the required data result.
+     *
+     * @param  array $tableIndexRows
+     * @param  string $tableName
+     * @return array
+     */
+    protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
+    {
+        $result = array();
+        foreach($tableIndexRows AS $tableIndex) {
+            $indexName = $keyName = $tableIndex['key_name'];
+            if($tableIndex['primary']) {
+                $keyName = 'primary';
+            }
+            $keyName = strtolower($keyName);
+
+            if(!isset($result[$keyName])) {
+                $result[$keyName] = array(
+                    'name' => $indexName,
+                    'columns' => array($tableIndex['column_name']),
+                    'unique' => $tableIndex['non_unique'] ? false : true,
+                    'primary' => $tableIndex['primary'],
+                );
+            } else {
+                $result[$keyName]['columns'][] = $tableIndex['column_name'];
+            }
+        }
+
+        $eventManager = $this->_platform->getEventManager();
+
+        $indexes = array();
+        foreach($result AS $indexKey => $data) {
+            $index = null;
+            $defaultPrevented = false;
+
+            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
+                $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn);
+                $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs);
+
+                $defaultPrevented = $eventArgs->isDefaultPrevented();
+                $index = $eventArgs->getIndex();
+            }
+
+            if (!$defaultPrevented) {
+                $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']);
+            }
+
+            if ($index) {
+                $indexes[$indexKey] = $index;
+            }
+        }
+
+        return $indexes;
+    }
+
+    protected function _getPortableTablesList($tables)
+    {
+        $list = array();
+        foreach ($tables as $key => $value) {
+            if ($value = $this->_getPortableTableDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableTableDefinition($table)
+    {
+        return $table;
+    }
+
+    protected function _getPortableUsersList($users)
+    {
+        $list = array();
+        foreach ($users as $key => $value) {
+            if ($value = $this->_getPortableUserDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableUserDefinition($user)
+    {
+        return $user;
+    }
+
+    protected function _getPortableViewsList($views)
+    {
+        $list = array();
+        foreach ($views as $key => $value) {
+            if ($view = $this->_getPortableViewDefinition($value)) {
+                $viewName = strtolower($view->getQuotedName($this->_platform));
+                $list[$viewName] = $view;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableViewDefinition($view)
+    {
+        return false;
+    }
+
+    protected function _getPortableTableForeignKeysList($tableForeignKeys)
+    {
+        $list = array();
+        foreach ($tableForeignKeys as $key => $value) {
+            if ($value = $this->_getPortableTableForeignKeyDefinition($value)) {
+                $list[] = $value;
+            }
+        }
+        return $list;
+    }
+
+    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
+    {
+        return $tableForeignKey;
+    }
+
+    protected function _execSql($sql)
+    {
+        foreach ((array) $sql as $query) {
+            $this->_conn->executeUpdate($query);
+        }
+    }
+
+    /**
+     * Create a schema instance for the current database.
+     *
+     * @return Schema
+     */
+    public function createSchema()
+    {
+        $sequences = array();
+        if($this->_platform->supportsSequences()) {
+            $sequences = $this->listSequences();
+        }
+        $tables = $this->listTables();
+
+        return new Schema($tables, $sequences, $this->createSchemaConfig());
+    }
+
+    /**
+     * Create the configuration for this schema.
+     *
+     * @return SchemaConfig
+     */
+    public function createSchemaConfig()
+    {
+        $schemaConfig = new SchemaConfig();
+        $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength());
+
+        $searchPaths = $this->getSchemaSearchPaths();
+        if (isset($searchPaths[0])) {
+            $schemaConfig->setName($searchPaths[0]);
+        }
+
+        return $schemaConfig;
+    }
+
+    /**
+     * The search path for namespaces in the currently connected database.
+     *
+     * The first entry is usually the default namespace in the Schema. All
+     * further namespaces contain tables/sequences which can also be addressed
+     * with a short, not full-qualified name.
+     *
+     * For databases that don't support subschema/namespaces this method
+     * returns the name of the currently connected database.
+     *
+     * @return array
+     */
+    public function getSchemaSearchPaths()
+    {
+        return array($this->_conn->getDatabase());
+    }
+
+    /**
+     * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
+     * the type given as default.
+     *
+     * @param  string $comment
+     * @param  string $currentType
+     * @return string
+     */
+    public function extractDoctrineTypeFromComment($comment, $currentType)
+    {
+        if (preg_match("(\(DC2Type:([a-zA-Z0-9]+)\))", $comment, $match)) {
+            $currentType = $match[1];
+        }
+        return $currentType;
+    }
+
+    public function removeDoctrineTypeFromComment($comment, $type)
+    {
+        return str_replace('(DC2Type:'.$type.')', '', $comment);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Column.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Column.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Column.php	(revision 345)
@@ -0,0 +1,423 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use \Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+
+/**
+ * Object representation of a database column
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Column extends AbstractAsset
+{
+    /**
+     * @var \Doctrine\DBAL\Types\Type
+     */
+    protected $_type;
+
+    /**
+     * @var int
+     */
+    protected $_length = null;
+
+    /**
+     * @var int
+     */
+    protected $_precision = 10;
+
+    /**
+     * @var int
+     */
+    protected $_scale = 0;
+
+    /**
+     * @var bool
+     */
+    protected $_unsigned = false;
+
+    /**
+     * @var bool
+     */
+    protected $_fixed = false;
+
+    /**
+     * @var bool
+     */
+    protected $_notnull = true;
+
+    /**
+     * @var string
+     */
+    protected $_default = null;
+
+    /**
+     * @var bool
+     */
+    protected $_autoincrement = false;
+
+    /**
+     * @var array
+     */
+    protected $_platformOptions = array();
+
+    /**
+     * @var string
+     */
+    protected $_columnDefinition = null;
+
+    /**
+     * @var string
+     */
+    protected $_comment = null;
+
+    /**
+     * @var array
+     */
+    protected $_customSchemaOptions = array();
+
+    /**
+     * Create a new Column
+     *
+     * @param string $columnName
+     * @param Doctrine\DBAL\Types\Type $type
+     * @param int $length
+     * @param bool $notNull
+     * @param mixed $default
+     * @param bool $unsigned
+     * @param bool $fixed
+     * @param int $precision
+     * @param int $scale
+     * @param array $platformOptions
+     */
+    public function __construct($columnName, Type $type, array $options=array())
+    {
+        $this->_setName($columnName);
+        $this->setType($type);
+        $this->setOptions($options);
+    }
+
+    /**
+     * @param array $options
+     * @return Column
+     */
+    public function setOptions(array $options)
+    {
+        foreach ($options AS $name => $value) {
+            $method = "set".$name;
+            if (method_exists($this, $method)) {
+                $this->$method($value);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @param Type $type
+     * @return Column
+     */
+    public function setType(Type $type)
+    {
+        $this->_type = $type;
+        return $this;
+    }
+
+    /**
+     * @param int $length
+     * @return Column
+     */
+    public function setLength($length)
+    {
+        if($length !== null) {
+            $this->_length = (int)$length;
+        } else {
+            $this->_length = null;
+        }
+        return $this;
+    }
+
+    /**
+     * @param int $precision
+     * @return Column
+     */
+    public function setPrecision($precision)
+    {
+        if (!is_numeric($precision)) {
+            $precision = 10; // defaults to 10 when no valid precision is given.
+        }
+
+        $this->_precision = (int)$precision;
+        return $this;
+    }
+
+    /**
+     * @param  int $scale
+     * @return Column
+     */
+    public function setScale($scale)
+    {
+        if (!is_numeric($scale)) {
+            $scale = 0;
+        }
+
+        $this->_scale = (int)$scale;
+        return $this;
+    }
+
+    /**
+     *
+     * @param  bool $unsigned
+     * @return Column
+     */
+    public function setUnsigned($unsigned)
+    {
+        $this->_unsigned = (bool)$unsigned;
+        return $this;
+    }
+
+    /**
+     *
+     * @param  bool $fixed
+     * @return Column
+     */
+    public function setFixed($fixed)
+    {
+        $this->_fixed = (bool)$fixed;
+        return $this;
+    }
+
+    /**
+     * @param  bool $notnull
+     * @return Column
+     */
+    public function setNotnull($notnull)
+    {
+        $this->_notnull = (bool)$notnull;
+        return $this;
+    }
+
+    /**
+     *
+     * @param  mixed $default
+     * @return Column
+     */
+    public function setDefault($default)
+    {
+        $this->_default = $default;
+        return $this;
+    }
+
+    /**
+     *
+     * @param array $platformOptions
+     * @return Column
+     */
+    public function setPlatformOptions(array $platformOptions)
+    {
+        $this->_platformOptions = $platformOptions;
+        return $this;
+    }
+
+    /**
+     *
+     * @param  string $name
+     * @param  mixed $value
+     * @return Column
+     */
+    public function setPlatformOption($name, $value)
+    {
+        $this->_platformOptions[$name] = $value;
+        return $this;
+    }
+
+    /**
+     *
+     * @param  string
+     * @return Column
+     */
+    public function setColumnDefinition($value)
+    {
+        $this->_columnDefinition = $value;
+        return $this;
+    }
+
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    public function getLength()
+    {
+        return $this->_length;
+    }
+
+    public function getPrecision()
+    {
+        return $this->_precision;
+    }
+
+    public function getScale()
+    {
+        return $this->_scale;
+    }
+
+    public function getUnsigned()
+    {
+        return $this->_unsigned;
+    }
+
+    public function getFixed()
+    {
+        return $this->_fixed;
+    }
+
+    public function getNotnull()
+    {
+        return $this->_notnull;
+    }
+
+    public function getDefault()
+    {
+        return $this->_default;
+    }
+
+    public function getPlatformOptions()
+    {
+        return $this->_platformOptions;
+    }
+
+    public function hasPlatformOption($name)
+    {
+        return isset($this->_platformOptions[$name]);
+    }
+
+    public function getPlatformOption($name)
+    {
+        return $this->_platformOptions[$name];
+    }
+
+    public function getColumnDefinition()
+    {
+        return $this->_columnDefinition;
+    }
+
+    public function getAutoincrement()
+    {
+        return $this->_autoincrement;
+    }
+
+    public function setAutoincrement($flag)
+    {
+        $this->_autoincrement = $flag;
+        return $this;
+    }
+
+    public function setComment($comment)
+    {
+        $this->_comment = $comment;
+        return $this;
+    }
+
+    public function getComment()
+    {
+        return $this->_comment;
+    }
+
+    /**
+     * @param  string $name
+     * @param  mixed $value
+     * @return Column
+     */
+    public function setCustomSchemaOption($name, $value)
+    {
+        $this->_customSchemaOptions[$name] = $value;
+        return $this;
+    }
+
+    /**
+     * @param  string $name
+     * @return boolean
+     */
+    public function hasCustomSchemaOption($name)
+    {
+        return isset($this->_customSchemaOptions[$name]);
+    }
+
+    /**
+     * @param  string $name
+     * @return mixed
+     */
+    public function getCustomSchemaOption($name)
+    {
+        return $this->_customSchemaOptions[$name];
+    }
+
+    /**
+     * @param array $customSchemaOptions
+     * @return Column
+     */
+    public function setCustomSchemaOptions(array $customSchemaOptions)
+    {
+        $this->_customSchemaOptions = $customSchemaOptions;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getCustomSchemaOptions()
+    {
+        return $this->_customSchemaOptions;
+    }
+
+    /**
+     * @param Visitor $visitor
+     */
+    public function visit(\Doctrine\DBAL\Schema\Visitor $visitor)
+    {
+        $visitor->accept($this);
+    }
+
+    /**
+     * @return array
+     */
+    public function toArray()
+    {
+        return array_merge(array(
+            'name'          => $this->_name,
+            'type'          => $this->_type,
+            'default'       => $this->_default,
+            'notnull'       => $this->_notnull,
+            'length'        => $this->_length,
+            'precision'     => $this->_precision,
+            'scale'         => $this->_scale,
+            'fixed'         => $this->_fixed,
+            'unsigned'      => $this->_unsigned,
+            'autoincrement' => $this->_autoincrement,
+            'columnDefinition' => $this->_columnDefinition,
+            'comment' => $this->_comment,
+        ), $this->_platformOptions, $this->_customSchemaOptions);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ColumnDiff.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ColumnDiff.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ColumnDiff.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Represent the change of a column
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ColumnDiff
+{
+    public $oldColumnName;
+
+    /**
+     * @var Column
+     */
+    public $column;
+
+    /**
+     * @var array
+     */
+    public $changedProperties = array();
+
+    public function __construct($oldColumnName, Column $column, array $changedProperties = array())
+    {
+        $this->oldColumnName = $oldColumnName;
+        $this->column = $column;
+        $this->changedProperties = $changedProperties;
+    }
+
+    public function hasChanged($propertyName)
+    {
+        return in_array($propertyName, $this->changedProperties);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Comparator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Comparator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Comparator.php	(revision 345)
@@ -0,0 +1,399 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Compare to Schemas and return an instance of SchemaDiff
+ *
+ * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Comparator
+{
+    /**
+     * @param Schema $fromSchema
+     * @param Schema $toSchema
+     * @return SchemaDiff
+     */
+    static public function compareSchemas( Schema $fromSchema, Schema $toSchema )
+    {
+        $c = new self();
+        return $c->compare($fromSchema, $toSchema);
+    }
+
+    /**
+     * Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema.
+     *
+     * The returned diferences are returned in such a way that they contain the
+     * operations to change the schema stored in $fromSchema to the schema that is
+     * stored in $toSchema.
+     *
+     * @param Schema $fromSchema
+     * @param Schema $toSchema
+     *
+     * @return SchemaDiff
+     */
+    public function compare(Schema $fromSchema, Schema $toSchema)
+    {
+        $diff = new SchemaDiff();
+
+        $foreignKeysToTable = array();
+
+        foreach ( $toSchema->getTables() AS $table ) {
+            $tableName = $table->getShortestName($toSchema->getName());
+            if ( ! $fromSchema->hasTable($tableName)) {
+                $diff->newTables[$tableName] = $toSchema->getTable($tableName);
+            } else {
+                $tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName));
+                if ($tableDifferences !== false) {
+                    $diff->changedTables[$tableName] = $tableDifferences;
+                }
+            }
+        }
+
+        /* Check if there are tables removed */
+        foreach ($fromSchema->getTables() AS $table) {
+            $tableName = $table->getShortestName($fromSchema->getName());
+
+            $table = $fromSchema->getTable($tableName);
+            if ( ! $toSchema->hasTable($tableName) ) {
+                $diff->removedTables[$tableName] = $table;
+            }
+
+            // also remember all foreign keys that point to a specific table
+            foreach ($table->getForeignKeys() AS $foreignKey) {
+                $foreignTable = strtolower($foreignKey->getForeignTableName());
+                if (!isset($foreignKeysToTable[$foreignTable])) {
+                    $foreignKeysToTable[$foreignTable] = array();
+                }
+                $foreignKeysToTable[$foreignTable][] = $foreignKey;
+            }
+        }
+
+        foreach ($diff->removedTables AS $tableName => $table) {
+            if (isset($foreignKeysToTable[$tableName])) {
+                $diff->orphanedForeignKeys = array_merge($diff->orphanedForeignKeys, $foreignKeysToTable[$tableName]);
+            }
+        }
+
+        foreach ($toSchema->getSequences() AS $sequence) {
+            $sequenceName = $sequence->getShortestName($toSchema->getName());
+            if (!$fromSchema->hasSequence($sequenceName)) {
+                $diff->newSequences[] = $sequence;
+            } else {
+                if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) {
+                    $diff->changedSequences[] = $toSchema->getSequence($sequenceName);
+                }
+            }
+        }
+
+        foreach ($fromSchema->getSequences() AS $sequence) {
+            $sequenceName = $sequence->getShortestName($fromSchema->getName());
+            if (!$toSchema->hasSequence($sequenceName)) {
+                $diff->removedSequences[] = $sequence;
+            }
+        }
+
+        return $diff;
+    }
+
+    /**
+     *
+     * @param Sequence $sequence1
+     * @param Sequence $sequence2
+     */
+    public function diffSequence(Sequence $sequence1, Sequence $sequence2)
+    {
+        if($sequence1->getAllocationSize() != $sequence2->getAllocationSize()) {
+            return true;
+        }
+
+        if($sequence1->getInitialValue() != $sequence2->getInitialValue()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the difference between the tables $table1 and $table2.
+     *
+     * If there are no differences this method returns the boolean false.
+     *
+     * @param Table $table1
+     * @param Table $table2
+     *
+     * @return bool|TableDiff
+     */
+    public function diffTable(Table $table1, Table $table2)
+    {
+        $changes = 0;
+        $tableDifferences = new TableDiff($table1->getName());
+
+        $table1Columns = $table1->getColumns();
+        $table2Columns = $table2->getColumns();
+
+        /* See if all the fields in table 1 exist in table 2 */
+        foreach ( $table2Columns as $columnName => $column ) {
+            if ( !$table1->hasColumn($columnName) ) {
+                $tableDifferences->addedColumns[$columnName] = $column;
+                $changes++;
+            }
+        }
+        /* See if there are any removed fields in table 2 */
+        foreach ( $table1Columns as $columnName => $column ) {
+            if ( !$table2->hasColumn($columnName) ) {
+                $tableDifferences->removedColumns[$columnName] = $column;
+                $changes++;
+            }
+        }
+
+        foreach ( $table1Columns as $columnName => $column ) {
+            if ( $table2->hasColumn($columnName) ) {
+                $changedProperties = $this->diffColumn( $column, $table2->getColumn($columnName) );
+                if (count($changedProperties) ) {
+                    $columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties);
+                    $tableDifferences->changedColumns[$column->getName()] = $columnDiff;
+                    $changes++;
+                }
+            }
+        }
+
+        $this->detectColumnRenamings($tableDifferences);
+
+        $table1Indexes = $table1->getIndexes();
+        $table2Indexes = $table2->getIndexes();
+
+        foreach ($table2Indexes AS $index2Name => $index2Definition) {
+            foreach ($table1Indexes AS $index1Name => $index1Definition) {
+                if ($this->diffIndex($index1Definition, $index2Definition) === false) {
+                    unset($table1Indexes[$index1Name]);
+                    unset($table2Indexes[$index2Name]);
+                } else {
+                    if ($index1Name == $index2Name) {
+                        $tableDifferences->changedIndexes[$index2Name] = $table2Indexes[$index2Name];
+                        unset($table1Indexes[$index1Name]);
+                        unset($table2Indexes[$index2Name]);
+                        $changes++;
+                    }
+                }
+            }
+        }
+
+        foreach ($table1Indexes AS $index1Name => $index1Definition) {
+            $tableDifferences->removedIndexes[$index1Name] = $index1Definition;
+            $changes++;
+        }
+
+        foreach ($table2Indexes AS $index2Name => $index2Definition) {
+            $tableDifferences->addedIndexes[$index2Name] = $index2Definition;
+            $changes++;
+        }
+
+        $fromFkeys = $table1->getForeignKeys();
+        $toFkeys = $table2->getForeignKeys();
+
+        foreach ($fromFkeys AS $key1 => $constraint1) {
+            foreach ($toFkeys AS $key2 => $constraint2) {
+                if($this->diffForeignKey($constraint1, $constraint2) === false) {
+                    unset($fromFkeys[$key1]);
+                    unset($toFkeys[$key2]);
+                } else {
+                    if (strtolower($constraint1->getName()) == strtolower($constraint2->getName())) {
+                        $tableDifferences->changedForeignKeys[] = $constraint2;
+                        $changes++;
+                        unset($fromFkeys[$key1]);
+                        unset($toFkeys[$key2]);
+                    }
+                }
+            }
+        }
+
+        foreach ($fromFkeys AS $key1 => $constraint1) {
+            $tableDifferences->removedForeignKeys[] = $constraint1;
+            $changes++;
+        }
+
+        foreach ($toFkeys AS $key2 => $constraint2) {
+            $tableDifferences->addedForeignKeys[] = $constraint2;
+            $changes++;
+        }
+
+        return $changes ? $tableDifferences : false;
+    }
+
+    /**
+     * Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
+     * however ambiguouties between different possibilites should not lead to renaming at all.
+     *
+     * @param TableDiff $tableDifferences
+     */
+    private function detectColumnRenamings(TableDiff $tableDifferences)
+    {
+        $renameCandidates = array();
+        foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) {
+            foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) {
+                if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
+                    $renameCandidates[$addedColumn->getName()][] = array($removedColumn, $addedColumn, $addedColumnName);
+                }
+            }
+        }
+
+        foreach ($renameCandidates AS $candidate => $candidateColumns) {
+            if (count($candidateColumns) == 1) {
+                list($removedColumn, $addedColumn) = $candidateColumns[0];
+                $removedColumnName = strtolower($removedColumn->getName());
+                $addedColumnName = strtolower($addedColumn->getName());
+
+                $tableDifferences->renamedColumns[$removedColumnName] = $addedColumn;
+                unset($tableDifferences->addedColumns[$addedColumnName]);
+                unset($tableDifferences->removedColumns[$removedColumnName]);
+            }
+        }
+    }
+
+    /**
+     * @param ForeignKeyConstraint $key1
+     * @param ForeignKeyConstraint $key2
+     * @return bool
+     */
+    public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2)
+    {
+        if (array_map('strtolower', $key1->getLocalColumns()) != array_map('strtolower', $key2->getLocalColumns())) {
+            return true;
+        }
+
+        if (array_map('strtolower', $key1->getForeignColumns()) != array_map('strtolower', $key2->getForeignColumns())) {
+            return true;
+        }
+
+        if ($key1->onUpdate() != $key2->onUpdate()) {
+            return true;
+        }
+
+        if ($key1->onDelete() != $key2->onDelete()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the difference between the fields $field1 and $field2.
+     *
+     * If there are differences this method returns $field2, otherwise the
+     * boolean false.
+     *
+     * @param Column $column1
+     * @param Column $column2
+     *
+     * @return array
+     */
+    public function diffColumn(Column $column1, Column $column2)
+    {
+        $changedProperties = array();
+        if ( $column1->getType() != $column2->getType() ) {
+            $changedProperties[] = 'type';
+        }
+
+        if ($column1->getNotnull() != $column2->getNotnull()) {
+            $changedProperties[] = 'notnull';
+        }
+
+        if ($column1->getDefault() != $column2->getDefault()) {
+            $changedProperties[] = 'default';
+        }
+
+        if ($column1->getUnsigned() != $column2->getUnsigned()) {
+            $changedProperties[] = 'unsigned';
+        }
+
+        if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) {
+            // check if value of length is set at all, default value assumed otherwise.
+            $length1 = $column1->getLength() ?: 255;
+            $length2 = $column2->getLength() ?: 255;
+            if ($length1 != $length2) {
+                $changedProperties[] = 'length';
+            }
+
+            if ($column1->getFixed() != $column2->getFixed()) {
+                $changedProperties[] = 'fixed';
+            }
+        }
+
+        if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) {
+            if (($column1->getPrecision()?:10) != ($column2->getPrecision()?:10)) {
+                $changedProperties[] = 'precision';
+            }
+            if ($column1->getScale() != $column2->getScale()) {
+                $changedProperties[] = 'scale';
+            }
+        }
+
+        if ($column1->getAutoincrement() != $column2->getAutoincrement()) {
+            $changedProperties[] = 'autoincrement';
+        }
+
+        // only allow to delete comment if its set to '' not to null.
+        if ($column1->getComment() !== null && $column1->getComment() != $column2->getComment()) {
+            $changedProperties[] = 'comment';
+        }
+
+        $options1 = $column1->getCustomSchemaOptions();
+        $options2 = $column2->getCustomSchemaOptions();
+
+        $commonKeys = array_keys(array_intersect_key($options1, $options2));
+
+        foreach ($commonKeys as $key) {
+            if ($options1[$key] !== $options2[$key]) {
+                $changedProperties[] = $key;
+            }
+        }
+
+        $diffKeys = array_keys(array_diff_key($options1, $options2) + array_diff_key($options2, $options1));
+
+        $changedProperties = array_merge($changedProperties, $diffKeys);
+
+        return $changedProperties;
+    }
+
+    /**
+     * Finds the difference between the indexes $index1 and $index2.
+     *
+     * Compares $index1 with $index2 and returns $index2 if there are any
+     * differences or false in case there are no differences.
+     *
+     * @param Index $index1
+     * @param Index $index2
+     * @return bool
+     */
+    public function diffIndex(Index $index1, Index $index2)
+    {
+        if ($index1->isFullfilledBy($index2) && $index2->isFullfilledBy($index1)) {
+            return false;
+        }
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Constraint.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Constraint.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Constraint.php	(revision 345)
@@ -0,0 +1,38 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Marker interface for contraints
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface Constraint
+{
+    public function getName();
+
+    public function getColumns();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/DB2SchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/DB2SchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/DB2SchemaManager.php	(revision 345)
@@ -0,0 +1,214 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
+
+/**
+ * IBM Db2 Schema Manager
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DB2SchemaManager extends AbstractSchemaManager
+{
+    /**
+     * Return a list of all tables in the current database
+     *
+     * Apparently creator is the schema not the user who created it:
+     * {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
+     *
+     * @return array
+     */
+    public function listTableNames()
+    {
+        $sql = $this->_platform->getListTablesSQL();
+        $sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')";
+
+        $tables = $this->_conn->fetchAll($sql);
+
+        return $this->_getPortableTablesList($tables);
+    }
+
+
+    /**
+     * Get Table Column Definition
+     *
+     * @param array $tableColumn
+     * @return Column
+     */
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $tableColumn = array_change_key_case($tableColumn, \CASE_LOWER);
+
+        $length = null;
+        $fixed = null;
+        $unsigned = false;
+        $scale = false;
+        $precision = false;
+
+        $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']);
+
+        switch (strtolower($tableColumn['typename'])) {
+            case 'varchar':
+                $length = $tableColumn['length'];
+                $fixed = false;
+                break;
+            case 'character':
+                $length = $tableColumn['length'];
+                $fixed = true;
+                break;
+            case 'clob':
+                $length = $tableColumn['length'];
+                break;
+            case 'decimal':
+            case 'double':
+            case 'real':
+                $scale = $tableColumn['scale'];
+                $precision = $tableColumn['length'];
+                break;
+        }
+
+        $options = array(
+            'length'        => $length,
+            'unsigned'      => (bool)$unsigned,
+            'fixed'         => (bool)$fixed,
+            'default'       => ($tableColumn['default'] == "NULL") ? null : $tableColumn['default'],
+            'notnull'       => (bool) ($tableColumn['nulls'] == 'N'),
+            'scale'         => null,
+            'precision'     => null,
+            'platformOptions' => array(),
+        );
+
+        if ($scale !== null && $precision !== null) {
+            $options['scale'] = $scale;
+            $options['precision'] = $precision;
+        }
+
+        return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+    protected function _getPortableTablesList($tables)
+    {
+        $tableNames = array();
+        foreach ($tables AS $tableRow) {
+            $tableRow = array_change_key_case($tableRow, \CASE_LOWER);
+            $tableNames[] = $tableRow['name'];
+        }
+        return $tableNames;
+    }
+
+    protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
+    {
+        $eventManager = $this->_platform->getEventManager();
+
+        $tableIndexRows = array();
+        $indexes = array();
+        foreach($tableIndexes AS $indexKey => $data) {
+            $data = array_change_key_case($data, \CASE_LOWER);
+            $unique = ($data['uniquerule'] == "D") ? false : true;
+            $primary = ($data['uniquerule'] == "P");
+
+            $indexName = strtolower($data['name']);
+            if ($primary) {
+                $keyName = 'primary';
+            } else {
+                $keyName = $indexName;
+            }
+
+            $data = array(
+                'name' => $indexName,
+                'columns' => explode("+", ltrim($data['colnames'], '+')),
+                'unique' => $unique,
+                'primary' => $primary
+            );
+
+            $index = null;
+            $defaultPrevented = false;
+
+            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
+                $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn);
+                $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs);
+
+                $defaultPrevented = $eventArgs->isDefaultPrevented();
+                $index = $eventArgs->getIndex();
+            }
+
+            if (!$defaultPrevented) {
+                $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']);
+            }
+
+            if ($index) {
+                $indexes[$indexKey] = $index;
+            }
+        }
+
+        return $indexes;
+    }
+
+    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
+    {
+        $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
+
+        $tableForeignKey['deleterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['deleterule']);
+        $tableForeignKey['updaterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['updaterule']);
+
+        return new ForeignKeyConstraint(
+            array_map('trim', (array)$tableForeignKey['fkcolnames']),
+            $tableForeignKey['reftbname'],
+            array_map('trim', (array)$tableForeignKey['pkcolnames']),
+            $tableForeignKey['relname'],
+            array(
+                'onUpdate' => $tableForeignKey['updaterule'],
+                'onDelete' => $tableForeignKey['deleterule'],
+            )
+        );
+    }
+
+    protected function _getPortableForeignKeyRuleDef($def)
+    {
+        if ($def == "C") {
+            return "CASCADE";
+        } else if ($def == "N") {
+            return "SET NULL";
+        }
+        return null;
+    }
+
+    protected function _getPortableViewDefinition($view)
+    {
+        $view = array_change_key_case($view, \CASE_LOWER);
+        // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199
+        //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']);
+        if (!is_resource($view['text'])) {
+            $pos = strpos($view['text'], ' AS ');
+            $sql = substr($view['text'], $pos+4);
+        } else {
+            $sql = '';
+        }
+
+        return new View($view['name'], $sql);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ForeignKeyConstraint.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ForeignKeyConstraint.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/ForeignKeyConstraint.php	(revision 345)
@@ -0,0 +1,164 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+
+class ForeignKeyConstraint extends AbstractAsset implements Constraint
+{
+    /**
+     * @var Table
+     */
+    protected $_localTable;
+
+    /**
+     * @var array
+     */
+    protected $_localColumnNames;
+
+    /**
+     * @var string
+     */
+    protected $_foreignTableName;
+
+    /**
+     * @var array
+     */
+    protected $_foreignColumnNames;
+
+    /**
+     * @var string
+     */
+    protected $_cascade = '';
+
+    /**
+     * @var array
+     */
+    protected $_options;
+
+    /**
+     *
+     * @param array $localColumnNames
+     * @param string $foreignTableName
+     * @param array $foreignColumnNames
+     * @param string $cascade
+     * @param string|null $name
+     */
+    public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name=null, array $options=array())
+    {
+        $this->_setName($name);
+        $this->_localColumnNames = $localColumnNames;
+        $this->_foreignTableName = $foreignTableName;
+        $this->_foreignColumnNames = $foreignColumnNames;
+        $this->_options = $options;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLocalTableName()
+    {
+        return $this->_localTable->getName();
+    }
+
+    /**
+     * @param Table $table
+     */
+    public function setLocalTable(Table $table)
+    {
+        $this->_localTable = $table;
+    }
+
+    /**
+     * @return array
+     */
+    public function getLocalColumns()
+    {
+        return $this->_localColumnNames;
+    }
+
+    public function getColumns()
+    {
+        return $this->_localColumnNames;
+    }
+
+    /**
+     * @return string
+     */
+    public function getForeignTableName()
+    {
+        return $this->_foreignTableName;
+    }
+
+    /**
+     * @return array
+     */
+    public function getForeignColumns()
+    {
+        return $this->_foreignColumnNames;
+    }
+
+    public function hasOption($name)
+    {
+        return isset($this->_options[$name]);
+    }
+
+    public function getOption($name)
+    {
+        return $this->_options[$name];
+    }
+
+    /**
+     * Foreign Key onUpdate status
+     *
+     * @return string|null
+     */
+    public function onUpdate()
+    {
+        return $this->_onEvent('onUpdate');
+    }
+
+    /**
+     * Foreign Key onDelete status
+     *
+     * @return string|null
+     */
+    public function onDelete()
+    {
+        return $this->_onEvent('onDelete');
+    }
+
+    /**
+     * @param  string $event
+     * @return string|null
+     */
+    private function _onEvent($event)
+    {
+        if (isset($this->_options[$event])) {
+            $onEvent = strtoupper($this->_options[$event]);
+            if (!in_array($onEvent, array('NO ACTION', 'RESTRICT'))) {
+                return $onEvent;
+            }
+        }
+        return false;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Index.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Index.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Index.php	(revision 345)
@@ -0,0 +1,188 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+
+class Index extends AbstractAsset implements Constraint
+{
+    /**
+     * @var array
+     */
+    protected $_columns;
+
+    /**
+     * @var bool
+     */
+    protected $_isUnique = false;
+
+    /**
+     * @var bool
+     */
+    protected $_isPrimary = false;
+
+    /**
+     * @param string $indexName
+     * @param array $column
+     * @param bool $isUnique
+     * @param bool $isPrimary
+     */
+    public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false)
+    {
+        $isUnique = ($isPrimary)?true:$isUnique;
+
+        $this->_setName($indexName);
+        $this->_isUnique = $isUnique;
+        $this->_isPrimary = $isPrimary;
+
+        foreach($columns AS $column) {
+            $this->_addColumn($column);
+        }
+    }
+
+    /**
+     * @param string $column
+     */
+    protected function _addColumn($column)
+    {
+        if(is_string($column)) {
+            $this->_columns[] = $column;
+        } else {
+            throw new \InvalidArgumentException("Expecting a string as Index Column");
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getColumns()
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * Is the index neither unique nor primary key?
+     *
+     * @return bool
+     */
+    public function isSimpleIndex()
+    {
+        return !$this->_isPrimary && !$this->_isUnique;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isUnique()
+    {
+        return $this->_isUnique;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isPrimary()
+    {
+        return $this->_isPrimary;
+    }
+
+    /**
+     * @param  string $columnName
+     * @param  int $pos
+     * @return bool
+     */
+    public function hasColumnAtPosition($columnName, $pos=0)
+    {
+        $columnName = strtolower($columnName);
+        $indexColumns = \array_map('strtolower', $this->getColumns());
+        return \array_search($columnName, $indexColumns) === $pos;
+    }
+
+    /**
+     * Check if this index exactly spans the given column names in the correct order.
+     *
+     * @param array $columnNames
+     * @return boolean
+     */
+    public function spansColumns(array $columnNames)
+    {
+        $sameColumns = true;
+        for ($i = 0; $i < count($this->_columns); $i++) {
+            if (!isset($columnNames[$i]) || strtolower($this->_columns[$i]) != strtolower($columnNames[$i])) {
+                $sameColumns = false;
+            }
+        }
+        return $sameColumns;
+    }
+
+    /**
+     * Check if the other index already fullfills all the indexing and constraint needs of the current one.
+     *
+     * @param Index $other
+     * @return bool
+     */
+    public function isFullfilledBy(Index $other)
+    {
+        // allow the other index to be equally large only. It being larger is an option
+        // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo)
+        if (count($other->getColumns()) != count($this->getColumns())) {
+            return false;
+        }
+
+        // Check if columns are the same, and even in the same order
+        $sameColumns = $this->spansColumns($other->getColumns());
+
+        if ($sameColumns) {
+            if (!$this->isUnique() && !$this->isPrimary()) {
+                // this is a special case: If the current key is neither primary or unique, any uniqe or
+                // primary key will always have the same effect for the index and there cannot be any constraint
+                // overlaps. This means a primary or unique index can always fullfill the requirements of just an
+                // index that has no constraints.
+                return true;
+            } else if ($other->isPrimary() != $this->isPrimary()) {
+                return false;
+            } else if ($other->isUnique() != $this->isUnique()) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Detect if the other index is a non-unique, non primary index that can be overwritten by this one.
+     *
+     * @param Index $other
+     * @return bool
+     */
+    public function overrules(Index $other)
+    {
+        if ($other->isPrimary()) {
+            return false;
+        } else if ($this->isSimpleIndex() && $other->isUnique()) {
+            return false;
+        }
+
+        if ($this->spansColumns($other->getColumns()) && ($this->isPrimary() || $this->isUnique())) {
+            return true;
+        }
+        return false;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/MySqlSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/MySqlSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/MySqlSchemaManager.php	(revision 345)
@@ -0,0 +1,213 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Schema manager for the MySql RDBMS.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @version     $Revision$
+ * @since       2.0
+ */
+class MySqlSchemaManager extends AbstractSchemaManager
+{
+    protected function _getPortableViewDefinition($view)
+    {
+        return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']);
+    }
+
+    protected function _getPortableTableDefinition($table)
+    {
+        return array_shift($table);
+    }
+
+    protected function _getPortableUserDefinition($user)
+    {
+        return array(
+            'user' => $user['User'],
+            'password' => $user['Password'],
+        );
+    }
+
+    protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
+    {
+        foreach($tableIndexes AS $k => $v) {
+            $v = array_change_key_case($v, CASE_LOWER);
+            if($v['key_name'] == 'PRIMARY') {
+                $v['primary'] = true;
+            } else {
+                $v['primary'] = false;
+            }
+            $tableIndexes[$k] = $v;
+        }
+
+        return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
+    }
+
+    protected function _getPortableSequenceDefinition($sequence)
+    {
+        return end($sequence);
+    }
+
+    protected function _getPortableDatabaseDefinition($database)
+    {
+        return $database['Database'];
+    }
+
+    /**
+     * Gets a portable column definition.
+     *
+     * The database type is mapped to a corresponding Doctrine mapping type.
+     *
+     * @param $tableColumn
+     * @return array
+     */
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
+
+        $dbType = strtolower($tableColumn['type']);
+        $dbType = strtok($dbType, '(), ');
+        if (isset($tableColumn['length'])) {
+            $length = $tableColumn['length'];
+            $decimal = '';
+        } else {
+            $length = strtok('(), ');
+            $decimal = strtok('(), ') ? strtok('(), '):null;
+        }
+        $type = array();
+        $unsigned = $fixed = null;
+
+        if ( ! isset($tableColumn['name'])) {
+            $tableColumn['name'] = '';
+        }
+
+        $scale = null;
+        $precision = null;
+
+        $type = $this->_platform->getDoctrineTypeMapping($dbType);
+        $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
+        $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
+
+        switch ($dbType) {
+            case 'char':
+                $fixed = true;
+                break;
+            case 'float':
+            case 'double':
+            case 'real':
+            case 'numeric':
+            case 'decimal':
+                if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['type'], $match)) {
+                    $precision = $match[1];
+                    $scale = $match[2];
+                    $length = null;
+                }
+                break;
+            case 'tinyint':
+            case 'smallint':
+            case 'mediumint':
+            case 'int':
+            case 'integer':
+            case 'bigint':
+            case 'tinyblob':
+            case 'mediumblob':
+            case 'longblob':
+            case 'blob':
+            case 'binary':
+            case 'varbinary':
+            case 'year':
+                $length = null;
+                break;
+        }
+
+        $length = ((int) $length == 0) ? null : (int) $length;
+        $def =  array(
+            'type' => $type,
+            'length' => $length,
+            'unsigned' => (bool) $unsigned,
+            'fixed' => (bool) $fixed
+        );
+
+        $options = array(
+            'length'        => $length,
+            'unsigned'      => (bool)$unsigned,
+            'fixed'         => (bool)$fixed,
+            'default'       => isset($tableColumn['default']) ? $tableColumn['default'] : null,
+            'notnull'       => (bool) ($tableColumn['null'] != 'YES'),
+            'scale'         => null,
+            'precision'     => null,
+            'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false),
+            'comment'       => (isset($tableColumn['comment'])) ? $tableColumn['comment'] : null
+        );
+
+        if ($scale !== null && $precision !== null) {
+            $options['scale'] = $scale;
+            $options['precision'] = $precision;
+        }
+
+        return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+    protected function _getPortableTableForeignKeysList($tableForeignKeys)
+    {
+        $list = array();
+        foreach ($tableForeignKeys as $key => $value) {
+            $value = array_change_key_case($value, CASE_LOWER);
+            if (!isset($list[$value['constraint_name']])) {
+                if (!isset($value['delete_rule']) || $value['delete_rule'] == "RESTRICT") {
+                    $value['delete_rule'] = null;
+                }
+                if (!isset($value['update_rule']) || $value['update_rule'] == "RESTRICT") {
+                    $value['update_rule'] = null;
+                }
+
+                $list[$value['constraint_name']] = array(
+                    'name' => $value['constraint_name'],
+                    'local' => array(),
+                    'foreign' => array(),
+                    'foreignTable' => $value['referenced_table_name'],
+                    'onDelete' => $value['delete_rule'],
+                    'onUpdate' => $value['update_rule'],
+                );
+            }
+            $list[$value['constraint_name']]['local'][] = $value['column_name'];
+            $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name'];
+        }
+
+        $result = array();
+        foreach($list AS $constraint) {
+            $result[] = new ForeignKeyConstraint(
+                array_values($constraint['local']), $constraint['foreignTable'],
+                array_values($constraint['foreign']), $constraint['name'],
+                array(
+                    'onDelete' => $constraint['onDelete'],
+                    'onUpdate' => $constraint['onUpdate'],
+                )
+            );
+        }
+
+        return $result;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/OracleSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/OracleSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/OracleSchemaManager.php	(revision 345)
@@ -0,0 +1,286 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Oracle Schema Manager
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @version     $Revision$
+ * @since       2.0
+ */
+class OracleSchemaManager extends AbstractSchemaManager
+{
+    protected function _getPortableViewDefinition($view)
+    {
+        $view = \array_change_key_case($view, CASE_LOWER);
+
+        return new View($view['view_name'], $view['text']);
+    }
+
+    protected function _getPortableUserDefinition($user)
+    {
+        $user = \array_change_key_case($user, CASE_LOWER);
+
+        return array(
+            'user' => $user['username'],
+        );
+    }
+
+    protected function _getPortableTableDefinition($table)
+    {
+        $table = \array_change_key_case($table, CASE_LOWER);
+
+        return $table['table_name'];
+    }
+
+    /**
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+     * @param  array $tableIndexes
+     * @param  string $tableName
+     * @return array
+     */
+    protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
+    {
+        $indexBuffer = array();
+        foreach ( $tableIndexes as $tableIndex ) {
+            $tableIndex = \array_change_key_case($tableIndex, CASE_LOWER);
+
+            $keyName = strtolower($tableIndex['name']);
+
+            if ( strtolower($tableIndex['is_primary']) == "p" ) {
+                $keyName = 'primary';
+                $buffer['primary'] = true;
+                $buffer['non_unique'] = false;
+            } else {
+                $buffer['primary'] = false;
+                $buffer['non_unique'] = ( $tableIndex['is_unique'] == 0 ) ? true : false;
+            }
+            $buffer['key_name'] = $keyName;
+            $buffer['column_name'] = $tableIndex['column_name'];
+            $indexBuffer[] = $buffer;
+        }
+        return parent::_getPortableTableIndexesList($indexBuffer, $tableName);
+    }
+
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $tableColumn = \array_change_key_case($tableColumn, CASE_LOWER);
+
+        $dbType = strtolower($tableColumn['data_type']);
+        if(strpos($dbType, "timestamp(") === 0) {
+            if (strpos($dbType, "WITH TIME ZONE")) {
+                $dbType = "timestamptz";
+            } else {
+                $dbType = "timestamp";
+            }
+        }
+
+        $type = array();
+        $length = $unsigned = $fixed = null;
+        if ( ! empty($tableColumn['data_length'])) {
+            $length = $tableColumn['data_length'];
+        }
+
+        if ( ! isset($tableColumn['column_name'])) {
+            $tableColumn['column_name'] = '';
+        }
+
+        if (stripos($tableColumn['data_default'], 'NULL') !== null) {
+            $tableColumn['data_default'] = null;
+        }
+
+        $precision = null;
+        $scale = null;
+
+        $type = $this->_platform->getDoctrineTypeMapping($dbType);
+        $type = $this->extractDoctrineTypeFromComment($tableColumn['comments'], $type);
+        $tableColumn['comments'] = $this->removeDoctrineTypeFromComment($tableColumn['comments'], $type);
+
+        switch ($dbType) {
+            case 'number':
+                if ($tableColumn['data_precision'] == 20 && $tableColumn['data_scale'] == 0) {
+                    $precision = 20;
+                    $scale = 0;
+                    $type = 'bigint';
+                } elseif ($tableColumn['data_precision'] == 5 && $tableColumn['data_scale'] == 0) {
+                    $type = 'smallint';
+                    $precision = 5;
+                    $scale = 0;
+                } elseif ($tableColumn['data_precision'] == 1 && $tableColumn['data_scale'] == 0) {
+                    $precision = 1;
+                    $scale = 0;
+                    $type = 'boolean';
+                } elseif ($tableColumn['data_scale'] > 0) {
+                    $precision = $tableColumn['data_precision'];
+                    $scale = $tableColumn['data_scale'];
+                    $type = 'decimal';
+                }
+                $length = null;
+                break;
+            case 'pls_integer':
+            case 'binary_integer':
+                $length = null;
+                break;
+            case 'varchar':
+            case 'varchar2':
+            case 'nvarchar2':
+                $length = $tableColumn['char_length'];
+                $fixed = false;
+                break;
+            case 'char':
+            case 'nchar':
+                $length = $tableColumn['char_length'];
+                $fixed = true;
+                break;
+            case 'date':
+            case 'timestamp':
+                $length = null;
+                break;
+            case 'float':
+                $precision = $tableColumn['data_precision'];
+                $scale = $tableColumn['data_scale'];
+                $length = null;
+                break;
+            case 'clob':
+            case 'nclob':
+                $length = null;
+                break;
+            case 'blob':
+            case 'raw':
+            case 'long raw':
+            case 'bfile':
+                $length = null;
+                break;
+            case 'rowid':
+            case 'urowid':
+            default:
+                $length = null;
+        }
+
+        $options = array(
+            'notnull'    => (bool) ($tableColumn['nullable'] === 'N'),
+            'fixed'      => (bool) $fixed,
+            'unsigned'   => (bool) $unsigned,
+            'default'    => $tableColumn['data_default'],
+            'length'     => $length,
+            'precision'  => $precision,
+            'scale'      => $scale,
+            'comment'       => (isset($tableColumn['comments'])) ? $tableColumn['comments'] : null,
+            'platformDetails' => array(),
+        );
+
+        return new Column($tableColumn['column_name'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+    protected function _getPortableTableForeignKeysList($tableForeignKeys)
+    {
+        $list = array();
+        foreach ($tableForeignKeys as $key => $value) {
+            $value = \array_change_key_case($value, CASE_LOWER);
+            if (!isset($list[$value['constraint_name']])) {
+                if ($value['delete_rule'] == "NO ACTION") {
+                    $value['delete_rule'] = null;
+                }
+
+                $list[$value['constraint_name']] = array(
+                    'name' => $value['constraint_name'],
+                    'local' => array(),
+                    'foreign' => array(),
+                    'foreignTable' => $value['references_table'],
+                    'onDelete' => $value['delete_rule'],
+                );
+            }
+            $list[$value['constraint_name']]['local'][$value['position']] = $value['local_column'];
+            $list[$value['constraint_name']]['foreign'][$value['position']] = $value['foreign_column'];
+        }
+
+        $result = array();
+        foreach($list AS $constraint) {
+            $result[] = new ForeignKeyConstraint(
+                array_values($constraint['local']), $constraint['foreignTable'],
+                array_values($constraint['foreign']),  $constraint['name'],
+                array('onDelete' => $constraint['onDelete'])
+            );
+        }
+
+        return $result;
+    }
+
+    protected function _getPortableSequenceDefinition($sequence)
+    {
+        $sequence = \array_change_key_case($sequence, CASE_LOWER);
+        return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['min_value']);
+    }
+
+    protected function _getPortableFunctionDefinition($function)
+    {
+        $function = \array_change_key_case($function, CASE_LOWER);
+        return $function['name'];
+    }
+
+    protected function _getPortableDatabaseDefinition($database)
+    {
+        $database = \array_change_key_case($database, CASE_LOWER);
+        return $database['username'];
+    }
+
+    public function createDatabase($database = null)
+    {
+        if (is_null($database)) {
+            $database = $this->_conn->getDatabase();
+        }
+
+        $params = $this->_conn->getParams();
+        $username   = $database;
+        $password   = $params['password'];
+
+        $query  = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
+        $result = $this->_conn->executeUpdate($query);
+
+        $query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username;
+        $result = $this->_conn->executeUpdate($query);
+
+        return true;
+    }
+
+    public function dropAutoincrement($table)
+    {
+        $sql = $this->_platform->getDropAutoincrementSql($table);
+        foreach ($sql as $query) {
+            $this->_conn->executeUpdate($query);
+        }
+
+        return true;
+    }
+
+    public function dropTable($name)
+    {
+        $this->dropAutoincrement($name);
+
+        return parent::dropTable($name);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php	(revision 345)
@@ -0,0 +1,359 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * PostgreSQL Schema Manager
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @since       2.0
+ */
+class PostgreSqlSchemaManager extends AbstractSchemaManager
+{
+    /**
+     * @var array
+     */
+    private $existingSchemaPaths;
+
+    /**
+     * Get all the existing schema names.
+     *
+     * @return array
+     */
+    public function getSchemaNames()
+    {
+        $rows = $this->_conn->fetchAll('SELECT schema_name FROM information_schema.schemata');
+        return array_map(function($v) { return $v['schema_name']; }, $rows);
+    }
+
+    /**
+     * Return an array of schema search paths
+     *
+     * This is a PostgreSQL only function.
+     *
+     * @return array
+     */
+    public function getSchemaSearchPaths()
+    {
+        $params = $this->_conn->getParams();
+        $schema = explode(",", $this->_conn->fetchColumn('SHOW search_path'));
+        if (isset($params['user'])) {
+            $schema = str_replace('"$user"', $params['user'], $schema);
+        }
+        return $schema;
+    }
+
+    /**
+     * Get names of all existing schemas in the current users search path.
+     *
+     * This is a PostgreSQL only function.
+     *
+     * @return array
+     */
+    public function getExistingSchemaSearchPaths()
+    {
+        if ($this->existingSchemaPaths === null) {
+            $this->determineExistingSchemaSearchPaths();
+        }
+        return $this->existingSchemaPaths;
+    }
+
+    /**
+     * Use this to set or reset the order of the existing schemas in the current search path of the user
+     *
+     * This is a PostgreSQL only function.
+     *
+     * @return type
+     */
+    public function determineExistingSchemaSearchPaths()
+    {
+        $names = $this->getSchemaNames();
+        $paths = $this->getSchemaSearchPaths();
+
+        $this->existingSchemaPaths = array_filter($paths, function ($v) use ($names) {
+            return in_array($v, $names);
+        });
+    }
+
+    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
+    {
+        $onUpdate = null;
+        $onDelete = null;
+
+        if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) {
+            $onUpdate = $match[1];
+        }
+        if (preg_match('(ON DELETE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) {
+            $onDelete = $match[1];
+        }
+
+        if (preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) {
+            // PostgreSQL returns identifiers that are keywords with quotes, we need them later, don't get
+            // the idea to trim them here.
+            $localColumns = array_map('trim', explode(",", $values[1]));
+            $foreignColumns = array_map('trim', explode(",", $values[3]));
+            $foreignTable = $values[2];
+        }
+
+        return new ForeignKeyConstraint(
+                $localColumns, $foreignTable, $foreignColumns, $tableForeignKey['conname'],
+                array('onUpdate' => $onUpdate, 'onDelete' => $onDelete)
+        );
+    }
+
+    public function dropDatabase($database)
+    {
+        $params = $this->_conn->getParams();
+        $params["dbname"] = "postgres";
+        $tmpPlatform = $this->_platform;
+        $tmpConn = $this->_conn;
+
+        $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
+        $this->_platform = $this->_conn->getDatabasePlatform();
+
+        parent::dropDatabase($database);
+
+        $this->_platform = $tmpPlatform;
+        $this->_conn = $tmpConn;
+    }
+
+    public function createDatabase($database)
+    {
+        $params = $this->_conn->getParams();
+        $params["dbname"] = "postgres";
+        $tmpPlatform = $this->_platform;
+        $tmpConn = $this->_conn;
+
+        $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
+        $this->_platform = $this->_conn->getDatabasePlatform();
+
+        parent::createDatabase($database);
+
+        $this->_platform = $tmpPlatform;
+        $this->_conn = $tmpConn;
+    }
+
+    protected function _getPortableTriggerDefinition($trigger)
+    {
+        return $trigger['trigger_name'];
+    }
+
+    protected function _getPortableViewDefinition($view)
+    {
+        return new View($view['viewname'], $view['definition']);
+    }
+
+    protected function _getPortableUserDefinition($user)
+    {
+        return array(
+            'user' => $user['usename'],
+            'password' => $user['passwd']
+        );
+    }
+
+    protected function _getPortableTableDefinition($table)
+    {
+        $schemas = $this->getExistingSchemaSearchPaths();
+        $firstSchema = array_shift($schemas);
+
+        if ($table['schema_name'] == $firstSchema) {
+            return $table['table_name'];
+        } else {
+            return $table['schema_name'] . "." . $table['table_name'];
+        }
+    }
+
+    /**
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+     * @param  array $tableIndexes
+     * @param  string $tableName
+     * @return array
+     */
+    protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
+    {
+        $buffer = array();
+        foreach ($tableIndexes AS $row) {
+            $colNumbers = explode(' ', $row['indkey']);
+            $colNumbersSql = 'IN (' . join(' ,', $colNumbers) . ' )';
+            $columnNameSql = "SELECT attnum, attname FROM pg_attribute
+                WHERE attrelid={$row['indrelid']} AND attnum $colNumbersSql ORDER BY attnum ASC;";
+
+            $stmt = $this->_conn->executeQuery($columnNameSql);
+            $indexColumns = $stmt->fetchAll();
+
+            // required for getting the order of the columns right.
+            foreach ($colNumbers AS $colNum) {
+                foreach ($indexColumns as $colRow) {
+                    if ($colNum == $colRow['attnum']) {
+                        $buffer[] = array(
+                            'key_name' => $row['relname'],
+                            'column_name' => trim($colRow['attname']),
+                            'non_unique' => !$row['indisunique'],
+                            'primary' => $row['indisprimary']
+                        );
+                    }
+                }
+            }
+        }
+        return parent::_getPortableTableIndexesList($buffer, $tableName);
+    }
+
+    protected function _getPortableDatabaseDefinition($database)
+    {
+        return $database['datname'];
+    }
+
+    protected function _getPortableSequenceDefinition($sequence)
+    {
+        if ($sequence['schemaname'] != 'public') {
+            $sequenceName = $sequence['schemaname'] . "." . $sequence['relname'];
+        } else {
+            $sequenceName = $sequence['relname'];
+        }
+
+        $data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $sequenceName);
+        return new Sequence($sequenceName, $data[0]['increment_by'], $data[0]['min_value']);
+    }
+
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
+
+        if (strtolower($tableColumn['type']) === 'varchar') {
+            // get length from varchar definition
+            $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']);
+            $tableColumn['length'] = $length;
+        }
+
+        $matches = array();
+
+        $autoincrement = false;
+        if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches)) {
+            $tableColumn['sequence'] = $matches[1];
+            $tableColumn['default'] = null;
+            $autoincrement = true;
+        }
+
+        if (stripos($tableColumn['default'], 'NULL') === 0) {
+            $tableColumn['default'] = null;
+        }
+
+        $length = (isset($tableColumn['length'])) ? $tableColumn['length'] : null;
+        if ($length == '-1' && isset($tableColumn['atttypmod'])) {
+            $length = $tableColumn['atttypmod'] - 4;
+        }
+        if ((int) $length <= 0) {
+            $length = null;
+        }
+        $fixed = null;
+
+        if (!isset($tableColumn['name'])) {
+            $tableColumn['name'] = '';
+        }
+
+        $precision = null;
+        $scale = null;
+
+        $dbType = strtolower($tableColumn['type']);
+        if (strlen($tableColumn['domain_type']) && !$this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])) {
+            $dbType = strtolower($tableColumn['domain_type']);
+            $tableColumn['complete_type'] = $tableColumn['domain_complete_type'];
+        }
+
+        $type = $this->_platform->getDoctrineTypeMapping($dbType);
+        $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
+        $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
+
+        switch ($dbType) {
+            case 'smallint':
+            case 'int2':
+                $length = null;
+                break;
+            case 'int':
+            case 'int4':
+            case 'integer':
+                $length = null;
+                break;
+            case 'bigint':
+            case 'int8':
+                $length = null;
+                break;
+            case 'bool':
+            case 'boolean':
+                $length = null;
+                break;
+            case 'text':
+                $fixed = false;
+                break;
+            case 'varchar':
+            case 'interval':
+            case '_varchar':
+                $fixed = false;
+                break;
+            case 'char':
+            case 'bpchar':
+                $fixed = true;
+                break;
+            case 'float':
+            case 'float4':
+            case 'float8':
+            case 'double':
+            case 'double precision':
+            case 'real':
+            case 'decimal':
+            case 'money':
+            case 'numeric':
+                if (preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) {
+                    $precision = $match[1];
+                    $scale = $match[2];
+                    $length = null;
+                }
+                break;
+            case 'year':
+                $length = null;
+                break;
+        }
+
+        if ($tableColumn['default'] && preg_match("('([^']+)'::)", $tableColumn['default'], $match)) {
+            $tableColumn['default'] = $match[1];
+        }
+
+        $options = array(
+            'length'        => $length,
+            'notnull'       => (bool) $tableColumn['isnotnull'],
+            'default'       => $tableColumn['default'],
+            'primary'       => (bool) ($tableColumn['pri'] == 't'),
+            'precision'     => $precision,
+            'scale'         => $scale,
+            'fixed'         => $fixed,
+            'unsigned'      => false,
+            'autoincrement' => $autoincrement,
+            'comment'       => $tableColumn['comment'],
+        );
+
+        return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SQLServerSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SQLServerSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SQLServerSchemaManager.php	(revision 345)
@@ -0,0 +1,216 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
+use Doctrine\DBAL\Events;
+
+/**
+ * SQL Server Schema Manager
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Juozas Kaziukenas <juozas@juokaz.com>
+ * @since       2.0
+ */
+class SQLServerSchemaManager extends AbstractSchemaManager
+{
+    /**
+     * @override
+     */
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $dbType = strtolower($tableColumn['TYPE_NAME']);
+
+        $autoincrement = false;
+        if (stripos($dbType, 'identity')) {
+            $dbType = trim(str_ireplace('identity', '', $dbType));
+            $autoincrement = true;
+        }
+
+        $type = array();
+        $unsigned = $fixed = null;
+
+        if (!isset($tableColumn['name'])) {
+            $tableColumn['name'] = '';
+        }
+
+        $default = $tableColumn['COLUMN_DEF'];
+
+        while ($default != ($default2 = preg_replace("/^\((.*)\)$/", '$1', $default))) {
+            $default = trim($default2, "'");
+        }
+
+        $length = (int) $tableColumn['LENGTH'];
+
+        $type = $this->_platform->getDoctrineTypeMapping($dbType);
+        switch ($type) {
+            case 'char':
+                if ($tableColumn['LENGTH'] == '1') {
+                    $type = 'boolean';
+                    if (preg_match('/^(is|has)/', $tableColumn['name'])) {
+                        $type = array_reverse($type);
+                    }
+                }
+                $fixed = true;
+                break;
+            case 'text':
+                $fixed = false;
+                break;
+        }
+        switch ($dbType) {
+            case 'nchar':
+            case 'nvarchar':
+            case 'ntext':
+                // Unicode data requires 2 bytes per character
+                $length = $length / 2;
+                break;
+        }
+
+        $options = array(
+            'length' => ($length == 0 || !in_array($type, array('text', 'string'))) ? null : $length,
+            'unsigned' => (bool) $unsigned,
+            'fixed' => (bool) $fixed,
+            'default' => $default !== 'NULL' ? $default : null,
+            'notnull' => (bool) ($tableColumn['IS_NULLABLE'] != 'YES'),
+            'scale' => $tableColumn['SCALE'],
+            'precision' => $tableColumn['PRECISION'],
+            'autoincrement' => $autoincrement,
+        );
+
+        return new Column($tableColumn['COLUMN_NAME'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+    /**
+     * @override
+     */
+    protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
+    {
+        $result = array();
+        foreach ($tableIndexRows AS $tableIndex) {
+            $indexName = $keyName = $tableIndex['index_name'];
+            if (strpos($tableIndex['index_description'], 'primary key') !== false) {
+                $keyName = 'primary';
+            }
+            $keyName = strtolower($keyName);
+
+            $result[$keyName] = array(
+                'name' => $indexName,
+                'columns' => explode(', ', $tableIndex['index_keys']),
+                'unique' => strpos($tableIndex['index_description'], 'unique') !== false,
+                'primary' => strpos($tableIndex['index_description'], 'primary key') !== false,
+            );
+        }
+
+        $eventManager = $this->_platform->getEventManager();
+
+        $indexes = array();
+        foreach ($result AS $indexKey => $data) {
+            $index = null;
+            $defaultPrevented = false;
+
+            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
+                $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn);
+                $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs);
+
+                $defaultPrevented = $eventArgs->isDefaultPrevented();
+                $index = $eventArgs->getIndex();
+            }
+
+            if (!$defaultPrevented) {
+                $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']);
+            }
+
+            if ($index) {
+                $indexes[$indexKey] = $index;
+            }
+        }
+
+        return $indexes;
+    }
+
+    /**
+     * @override
+     */
+    public function _getPortableTableForeignKeyDefinition($tableForeignKey)
+    {
+        return new ForeignKeyConstraint(
+                (array) $tableForeignKey['ColumnName'],
+                $tableForeignKey['ReferenceTableName'],
+                (array) $tableForeignKey['ReferenceColumnName'],
+                $tableForeignKey['ForeignKey'],
+                array(
+                    'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']),
+                    'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']),
+                )
+        );
+    }
+
+    /**
+     * @override
+     */
+    protected function _getPortableTableDefinition($table)
+    {
+        return $table['name'];
+    }
+
+    /**
+     * @override
+     */
+    protected function _getPortableDatabaseDefinition($database)
+    {
+        return $database['name'];
+    }
+
+    /**
+     * @override
+     */
+    protected function _getPortableViewDefinition($view)
+    {
+        // @todo
+        return new View($view['name'], null);
+    }
+
+    /**
+     * List the indexes for a given table returning an array of Index instances.
+     *
+     * Keys of the portable indexes list are all lower-cased.
+     *
+     * @param string $table The name of the table
+     * @return Index[] $tableIndexes
+     */
+    public function listTableIndexes($table)
+    {
+        $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
+
+        try {
+            $tableIndexes = $this->_conn->fetchAll($sql);
+        } catch(\PDOException $e) {
+            if ($e->getCode() == "IMSSP") {
+                return array();
+            } else {
+                throw $e;
+            }
+        }
+
+        return $this->_getPortableTableIndexesList($tableIndexes, $table);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Schema.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Schema.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Schema.php	(revision 345)
@@ -0,0 +1,367 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Schema\Visitor\CreateSchemaSqlCollector;
+use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+
+/**
+ * Object representation of a database schema
+ *
+ * Different vendors have very inconsistent naming with regard to the concept
+ * of a "schema". Doctrine understands a schema as the entity that conceptually
+ * wraps a set of database objects such as tables, sequences, indexes and
+ * foreign keys that belong to each other into a namespace. A Doctrine Schema
+ * has nothing to do with the "SCHEMA" defined as in PostgreSQL, it is more
+ * related to the concept of "DATABASE" that exists in MySQL and PostgreSQL.
+ *
+ * Every asset in the doctrine schema has a name. A name consists of either a
+ * namespace.local name pair or just a local unqualified name.
+ *
+ * The abstraction layer that covers a PostgreSQL schema is the namespace of an
+ * database object (asset). A schema can have a name, which will be used as
+ * default namespace for the unqualified database objects that are created in
+ * the schema.
+ *
+ * In the case of MySQL where cross-database queries are allowed this leads to
+ * databases being "misinterpreted" as namespaces. This is intentional, however
+ * the CREATE/DROP SQL visitors will just filter this queries and do not
+ * execute them. Only the queries for the currently connected database are
+ * executed.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Schema extends AbstractAsset
+{
+    /**
+     * @var array
+     */
+    protected $_tables = array();
+
+    /**
+     * @var array
+     */
+    protected $_sequences = array();
+
+    /**
+     * @var SchemaConfig
+     */
+    protected $_schemaConfig = false;
+
+    /**
+     * @param array $tables
+     * @param array $sequences
+     * @param array $views
+     * @param array $triggers
+     * @param SchemaConfig $schemaConfig
+     */
+    public function __construct(array $tables=array(), array $sequences=array(), SchemaConfig $schemaConfig=null)
+    {
+        if ($schemaConfig == null) {
+            $schemaConfig = new SchemaConfig();
+        }
+        $this->_schemaConfig = $schemaConfig;
+        $this->_setName($schemaConfig->getName() ?: 'public');
+
+        foreach ($tables AS $table) {
+            $this->_addTable($table);
+        }
+        foreach ($sequences AS $sequence) {
+            $this->_addSequence($sequence);
+        }
+    }
+
+    /**
+     * @return bool
+     */
+    public function hasExplicitForeignKeyIndexes()
+    {
+        return $this->_schemaConfig->hasExplicitForeignKeyIndexes();
+    }
+
+    /**
+     * @param Table $table
+     */
+    protected function _addTable(Table $table)
+    {
+        $tableName = $table->getFullQualifiedName($this->getName());
+        if(isset($this->_tables[$tableName])) {
+            throw SchemaException::tableAlreadyExists($tableName);
+        }
+
+        $this->_tables[$tableName] = $table;
+        $table->setSchemaConfig($this->_schemaConfig);
+    }
+
+    /**
+     * @param Sequence $sequence
+     */
+    protected function _addSequence(Sequence $sequence)
+    {
+        $seqName = $sequence->getFullQualifiedName($this->getName());
+        if (isset($this->_sequences[$seqName])) {
+            throw SchemaException::sequenceAlreadyExists($seqName);
+        }
+        $this->_sequences[$seqName] = $sequence;
+    }
+
+    /**
+     * Get all tables of this schema.
+     *
+     * @return array
+     */
+    public function getTables()
+    {
+        return $this->_tables;
+    }
+
+    /**
+     * @param string $tableName
+     * @return Table
+     */
+    public function getTable($tableName)
+    {
+        $tableName = $this->getFullQualifiedAssetName($tableName);
+        if (!isset($this->_tables[$tableName])) {
+            throw SchemaException::tableDoesNotExist($tableName);
+        }
+
+        return $this->_tables[$tableName];
+    }
+
+    /**
+     * @return string
+     */
+    private function getFullQualifiedAssetName($name)
+    {
+        if ($this->isQuoted($name)) {
+            $name = $this->trimQuotes($name);
+        }
+        if (strpos($name, ".") === false) {
+            $name = $this->getName() . "." . $name;
+        }
+        return strtolower($name);
+    }
+
+    /**
+     * Does this schema have a table with the given name?
+     *
+     * @param  string $tableName
+     * @return Schema
+     */
+    public function hasTable($tableName)
+    {
+        $tableName = $this->getFullQualifiedAssetName($tableName);
+        return isset($this->_tables[$tableName]);
+    }
+
+    /**
+     * Get all table names, prefixed with a schema name, even the default one
+     * if present.
+     *
+     * @return array
+     */
+    public function getTableNames()
+    {
+        return array_keys($this->_tables);
+    }
+
+    public function hasSequence($sequenceName)
+    {
+        $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
+        return isset($this->_sequences[$sequenceName]);
+    }
+
+    /**
+     * @throws SchemaException
+     * @param  string $sequenceName
+     * @return Doctrine\DBAL\Schema\Sequence
+     */
+    public function getSequence($sequenceName)
+    {
+        $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
+        if(!$this->hasSequence($sequenceName)) {
+            throw SchemaException::sequenceDoesNotExist($sequenceName);
+        }
+        return $this->_sequences[$sequenceName];
+    }
+
+    /**
+     * @return Doctrine\DBAL\Schema\Sequence[]
+     */
+    public function getSequences()
+    {
+        return $this->_sequences;
+    }
+
+    /**
+     * Create a new table
+     *
+     * @param  string $tableName
+     * @return Table
+     */
+    public function createTable($tableName)
+    {
+        $table = new Table($tableName);
+        $this->_addTable($table);
+        return $table;
+    }
+
+    /**
+     * Rename a table
+     *
+     * @param string $oldTableName
+     * @param string $newTableName
+     * @return Schema
+     */
+    public function renameTable($oldTableName, $newTableName)
+    {
+        $table = $this->getTable($oldTableName);
+        $table->_setName($newTableName);
+
+        $this->dropTable($oldTableName);
+        $this->_addTable($table);
+        return $this;
+    }
+
+    /**
+     * Drop a table from the schema.
+     *
+     * @param string $tableName
+     * @return Schema
+     */
+    public function dropTable($tableName)
+    {
+        $tableName = $this->getFullQualifiedAssetName($tableName);
+        $table = $this->getTable($tableName);
+        unset($this->_tables[$tableName]);
+        return $this;
+    }
+
+    /**
+     * Create a new sequence
+     *
+     * @param  string $sequenceName
+     * @param  int $allocationSize
+     * @param  int $initialValue
+     * @return Sequence
+     */
+    public function createSequence($sequenceName, $allocationSize=1, $initialValue=1)
+    {
+        $seq = new Sequence($sequenceName, $allocationSize, $initialValue);
+        $this->_addSequence($seq);
+        return $seq;
+    }
+
+    /**
+     * @param string $sequenceName
+     * @return Schema
+     */
+    public function dropSequence($sequenceName)
+    {
+        $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
+        unset($this->_sequences[$sequenceName]);
+        return $this;
+    }
+
+    /**
+     * Return an array of necessary sql queries to create the schema on the given platform.
+     *
+     * @param AbstractPlatform $platform
+     * @return array
+     */
+    public function toSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        $sqlCollector = new CreateSchemaSqlCollector($platform);
+        $this->visit($sqlCollector);
+
+        return $sqlCollector->getQueries();
+    }
+
+    /**
+     * Return an array of necessary sql queries to drop the schema on the given platform.
+     *
+     * @param AbstractPlatform $platform
+     * @return array
+     */
+    public function toDropSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        $dropSqlCollector = new DropSchemaSqlCollector($platform);
+        $this->visit($dropSqlCollector);
+
+        return $dropSqlCollector->getQueries();
+    }
+
+    /**
+     * @param Schema $toSchema
+     * @param AbstractPlatform $platform
+     */
+    public function getMigrateToSql(Schema $toSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        $comparator = new Comparator();
+        $schemaDiff = $comparator->compare($this, $toSchema);
+        return $schemaDiff->toSql($platform);
+    }
+
+    /**
+     * @param Schema $fromSchema
+     * @param AbstractPlatform $platform
+     */
+    public function getMigrateFromSql(Schema $fromSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        $comparator = new Comparator();
+        $schemaDiff = $comparator->compare($fromSchema, $this);
+        return $schemaDiff->toSql($platform);
+    }
+
+    /**
+     * @param Visitor $visitor
+     */
+    public function visit(Visitor $visitor)
+    {
+        $visitor->acceptSchema($this);
+
+        foreach ($this->_tables AS $table) {
+            $table->visit($visitor);
+        }
+        foreach ($this->_sequences AS $sequence) {
+            $sequence->visit($visitor);
+        }
+    }
+
+    /**
+     * Cloning a Schema triggers a deep clone of all related assets.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        foreach ($this->_tables AS $k => $table) {
+            $this->_tables[$k] = clone $table;
+        }
+        foreach ($this->_sequences AS $k => $sequence) {
+            $this->_sequences[$k] = clone $sequence;
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaConfig.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaConfig.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaConfig.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Configuration for a Schema
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SchemaConfig
+{
+    /**
+     * @var bool
+     */
+    protected $_hasExplicitForeignKeyIndexes = false;
+
+    /**
+     * @var int
+     */
+    protected $_maxIdentifierLength = 63;
+
+    /**
+     * @var string
+     */
+    protected $_name;
+
+    /**
+     * @return bool
+     */
+    public function hasExplicitForeignKeyIndexes()
+    {
+        return $this->_hasExplicitForeignKeyIndexes;
+    }
+
+    /**
+     * @param bool $flag
+     */
+    public function setExplicitForeignKeyIndexes($flag)
+    {
+        $this->_hasExplicitForeignKeyIndexes = (bool)$flag;
+    }
+
+    /**
+     * @param int $length
+     */
+    public function setMaxIdentifierLength($length)
+    {
+        $this->_maxIdentifierLength = (int)$length;
+    }
+
+    /**
+     * @return int
+     */
+    public function getMaxIdentifierLength()
+    {
+        return $this->_maxIdentifierLength;
+    }
+
+    /**
+     * Get default namespace of schema objects.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * set default namespace name of schema objects.
+     *
+     * @param _name the value to set.
+     */
+    public function setName($name)
+    {
+        $this->_name = $name;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaDiff.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaDiff.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaDiff.php	(revision 345)
@@ -0,0 +1,176 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use \Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Schema Diff
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SchemaDiff
+{
+    /**
+     * All added tables
+     *
+     * @var array(string=>ezcDbSchemaTable)
+     */
+    public $newTables = array();
+
+    /**
+     * All changed tables
+     *
+     * @var array(string=>ezcDbSchemaTableDiff)
+     */
+    public $changedTables = array();
+
+    /**
+     * All removed tables
+     *
+     * @var array(string=>Table)
+     */
+    public $removedTables = array();
+
+    /**
+     * @var array
+     */
+    public $newSequences = array();
+
+    /**
+     * @var array
+     */
+    public $changedSequences = array();
+
+    /**
+     * @var array
+     */
+    public $removedSequences = array();
+
+    /**
+     * @var array
+     */
+    public $orphanedForeignKeys = array();
+
+    /**
+     * Constructs an SchemaDiff object.
+     *
+     * @param array(string=>Table)      $newTables
+     * @param array(string=>TableDiff)  $changedTables
+     * @param array(string=>bool)       $removedTables
+     */
+    public function __construct($newTables = array(), $changedTables = array(), $removedTables = array())
+    {
+        $this->newTables = $newTables;
+        $this->changedTables = $changedTables;
+        $this->removedTables = $removedTables;
+    }
+
+    /**
+     * The to save sql mode ensures that the following things don't happen:
+     *
+     * 1. Tables are deleted
+     * 2. Sequences are deleted
+     * 3. Foreign Keys which reference tables that would otherwise be deleted.
+     *
+     * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all.
+     *
+     * @param AbstractPlatform $platform
+     * @return array
+     */
+    public function toSaveSql(AbstractPlatform $platform)
+    {
+        return $this->_toSql($platform, true);
+    }
+
+    /**
+     * @param AbstractPlatform $platform
+     * @return array
+     */
+    public function toSql(AbstractPlatform $platform)
+    {
+        return $this->_toSql($platform, false);
+    }
+
+    /**
+     * @param AbstractPlatform $platform
+     * @param bool $saveMode
+     * @return array
+     */
+    protected function _toSql(AbstractPlatform $platform, $saveMode = false)
+    {
+        $sql = array();
+
+        if ($platform->supportsForeignKeyConstraints() && $saveMode == false) {
+            foreach ($this->orphanedForeignKeys AS $orphanedForeignKey) {
+                $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTableName());
+            }
+        }
+
+        if ($platform->supportsSequences() == true) {
+            foreach ($this->changedSequences AS $sequence) {
+                $sql[] = $platform->getAlterSequenceSQL($sequence);
+            }
+
+            if ($saveMode === false) {
+                foreach ($this->removedSequences AS $sequence) {
+                    $sql[] = $platform->getDropSequenceSQL($sequence);
+                }
+            }
+
+            foreach ($this->newSequences AS $sequence) {
+                $sql[] = $platform->getCreateSequenceSQL($sequence);
+            }
+        }
+
+        $foreignKeySql = array();
+        foreach ($this->newTables AS $table) {
+            $sql = array_merge(
+                $sql,
+                $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
+            );
+
+            if ($platform->supportsForeignKeyConstraints()) {
+                foreach ($table->getForeignKeys() AS $foreignKey) {
+                    $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
+                }
+            }
+        }
+        $sql = array_merge($sql, $foreignKeySql);
+
+        if ($saveMode === false) {
+            foreach ($this->removedTables AS $table) {
+                $sql[] = $platform->getDropTableSQL($table);
+            }
+        }
+
+        foreach ($this->changedTables AS $tableDiff) {
+            $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
+        }
+
+        return $sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SchemaException.php	(revision 345)
@@ -0,0 +1,126 @@
+<?php
+
+namespace Doctrine\DBAL\Schema;
+
+class SchemaException extends \Doctrine\DBAL\DBALException
+{
+    const TABLE_DOESNT_EXIST = 10;
+    const TABLE_ALREADY_EXISTS = 20;
+    const COLUMN_DOESNT_EXIST = 30;
+    const COLUMN_ALREADY_EXISTS = 40;
+    const INDEX_DOESNT_EXIST = 50;
+    const INDEX_ALREADY_EXISTS = 60;
+    const SEQUENCE_DOENST_EXIST = 70;
+    const SEQUENCE_ALREADY_EXISTS = 80;
+    const INDEX_INVALID_NAME = 90;
+    const FOREIGNKEY_DOESNT_EXIST = 100;
+
+    /**
+     * @param string $tableName
+     * @return SchemaException
+     */
+    static public function tableDoesNotExist($tableName)
+    {
+        return new self("There is no table with name '".$tableName."' in the schema.", self::TABLE_DOESNT_EXIST);
+    }
+
+    /**
+     * @param string $indexName
+     * @return SchemaException
+     */
+    static public function indexNameInvalid($indexName)
+    {
+        return new self("Invalid index-name $indexName given, has to be [a-zA-Z0-9_]", self::INDEX_INVALID_NAME);
+    }
+
+    /**
+     * @param string $indexName
+     * @return SchemaException
+     */
+    static public function indexDoesNotExist($indexName, $table)
+    {
+        return new self("Index '$indexName' does not exist on table '$table'.", self::INDEX_DOESNT_EXIST);
+    }
+
+    /**
+     * @param string $indexName
+     * @return SchemaException
+     */
+    static public function indexAlreadyExists($indexName, $table)
+    {
+        return new self("An index with name '$indexName' was already defined on table '$table'.", self::INDEX_ALREADY_EXISTS);
+    }
+
+    /**
+     * @param string $columnName
+     * @return SchemaException
+     */
+    static public function columnDoesNotExist($columnName, $table)
+    {
+        return new self("There is no column with name '$columnName' on table '$table'.", self::COLUMN_DOESNT_EXIST);
+    }
+
+    /**
+     *
+     * @param  string $tableName
+     * @return SchemaException
+     */
+    static public function tableAlreadyExists($tableName)
+    {
+        return new self("The table with name '".$tableName."' already exists.", self::TABLE_ALREADY_EXISTS);
+    }
+
+    /**
+     *
+     * @param string $tableName
+     * @param string $columnName
+     * @return SchemaException
+     */
+    static public function columnAlreadyExists($tableName, $columnName)
+    {
+        return new self(
+            "The column '".$columnName."' on table '".$tableName."' already exists.", self::COLUMN_ALREADY_EXISTS
+        );
+    }
+
+    /**
+     * @param string $sequenceName
+     * @return SchemaException
+     */
+    static public function sequenceAlreadyExists($sequenceName)
+    {
+        return new self("The sequence '".$sequenceName."' already exists.", self::SEQUENCE_ALREADY_EXISTS);
+    }
+
+    /**
+     * @param string $sequenceName
+     * @return SchemaException
+     */
+    static public function sequenceDoesNotExist($sequenceName)
+    {
+        return new self("There exists no sequence with the name '".$sequenceName."'.", self::SEQUENCE_DOENST_EXIST);
+    }
+
+    /**
+     * @param  string $fkName
+     * @return SchemaException
+     */
+    static public function foreignKeyDoesNotExist($fkName, $table)
+    {
+        return new self("There exists no foreign key with the name '$fkName' on table '$table'.", self::FOREIGNKEY_DOESNT_EXIST);
+    }
+
+    static public function namedForeignKeyRequired(Table $localTable, ForeignKeyConstraint $foreignKey)
+    {
+        return new self(
+            "The performed schema operation on ".$localTable->getName()." requires a named foreign key, ".
+            "but the given foreign key from (".implode(", ", $foreignKey->getColumns()).") onto foreign table ".
+            "'".$foreignKey->getForeignTableName()."' (".implode(", ", $foreignKey->getForeignColumns()).") is currently ".
+            "unnamed."
+        );
+    }
+
+    static public function alterTableChangeNotSupported($changeName) {
+        return new self ("Alter table change not supported, given '$changeName'");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Sequence.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Sequence.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Sequence.php	(revision 345)
@@ -0,0 +1,87 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+
+/**
+ * Sequence Structure
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Sequence extends AbstractAsset
+{
+    /**
+     * @var int
+     */
+    protected $_allocationSize = 1;
+
+    /**
+     * @var int
+     */
+    protected $_initialValue = 1;
+
+    /**
+     *
+     * @param string $name
+     * @param int $allocationSize
+     * @param int $initialValue
+     */
+    public function __construct($name, $allocationSize=1, $initialValue=1)
+    {
+        $this->_setName($name);
+        $this->_allocationSize = (is_numeric($allocationSize))?$allocationSize:1;
+        $this->_initialValue = (is_numeric($initialValue))?$initialValue:1;
+    }
+
+    public function getAllocationSize()
+    {
+        return $this->_allocationSize;
+    }
+
+    public function getInitialValue()
+    {
+        return $this->_initialValue;
+    }
+
+    public function setAllocationSize($allocationSize)
+    {
+        $this->_allocationSize = (is_numeric($allocationSize))?$allocationSize:1;
+    }
+
+    public function setInitialValue($initialValue)
+    {
+        $this->_initialValue = (is_numeric($initialValue))?$initialValue:1;
+    }
+
+    /**
+     * @param Visitor $visitor
+     */
+    public function visit(Visitor $visitor)
+    {
+        $visitor->acceptSequence($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SqliteSchemaManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SqliteSchemaManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/SqliteSchemaManager.php	(revision 345)
@@ -0,0 +1,190 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * SqliteSchemaManager
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @version     $Revision$
+ * @since       2.0
+ */
+class SqliteSchemaManager extends AbstractSchemaManager
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     */
+    public function dropDatabase($database)
+    {
+        if (file_exists($database)) {
+            unlink($database);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     */
+    public function createDatabase($database)
+    {
+        $params = $this->_conn->getParams();
+        $driver = $params['driver'];
+        $options = array(
+            'driver' => $driver,
+            'path' => $database
+        );
+        $conn = \Doctrine\DBAL\DriverManager::getConnection($options);
+        $conn->connect();
+        $conn->close();
+    }
+
+    protected function _getPortableTableDefinition($table)
+    {
+        return $table['name'];
+    }
+
+    /**
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+     * @param  array $tableIndexes
+     * @param  string $tableName
+     * @return array
+     */
+    protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
+    {
+        $indexBuffer = array();
+
+        // fetch primary
+        $stmt = $this->_conn->executeQuery( "PRAGMA TABLE_INFO ('$tableName')" );
+        $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC);
+        foreach($indexArray AS $indexColumnRow) {
+            if($indexColumnRow['pk'] == "1") {
+                $indexBuffer[] = array(
+                    'key_name' => 'primary',
+                    'primary' => true,
+                    'non_unique' => false,
+                    'column_name' => $indexColumnRow['name']
+                );
+            }
+        }
+
+        // fetch regular indexes
+        foreach($tableIndexes AS $tableIndex) {
+            // Ignore indexes with reserved names, e.g. autoindexes
+            if (strpos($tableIndex['name'], 'sqlite_') !== 0) {
+                $keyName = $tableIndex['name'];
+                $idx = array();
+                $idx['key_name'] = $keyName;
+                $idx['primary'] = false;
+                $idx['non_unique'] = $tableIndex['unique']?false:true;
+
+                $stmt = $this->_conn->executeQuery( "PRAGMA INDEX_INFO ( '{$keyName}' )" );
+                $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC);
+
+                foreach ( $indexArray as $indexColumnRow ) {
+                    $idx['column_name'] = $indexColumnRow['name'];
+                    $indexBuffer[] = $idx;
+                }
+            }
+        }
+
+        return parent::_getPortableTableIndexesList($indexBuffer, $tableName);
+    }
+
+    protected function _getPortableTableIndexDefinition($tableIndex)
+    {
+        return array(
+            'name' => $tableIndex['name'],
+            'unique' => (bool) $tableIndex['unique']
+        );
+    }
+
+    protected function _getPortableTableColumnDefinition($tableColumn)
+    {
+        $e = explode('(', $tableColumn['type']);
+        $tableColumn['type'] = $e[0];
+        if (isset($e[1])) {
+            $length = trim($e[1], ')');
+            $tableColumn['length'] = $length;
+        }
+
+        $dbType = strtolower($tableColumn['type']);
+        $length = isset($tableColumn['length']) ? $tableColumn['length'] : null;
+        $unsigned = (boolean) isset($tableColumn['unsigned']) ? $tableColumn['unsigned'] : false;
+        $fixed = false;
+        $type = $this->_platform->getDoctrineTypeMapping($dbType);
+        $default = $tableColumn['dflt_value'];
+        if  ($default == 'NULL') {
+            $default = null;
+        }
+        if ($default !== null) {
+            // SQLite returns strings wrapped in single quotes, so we need to strip them
+            $default = preg_replace("/^'(.*)'$/", '\1', $default);
+        }
+        $notnull = (bool) $tableColumn['notnull'];
+
+        if ( ! isset($tableColumn['name'])) {
+            $tableColumn['name'] = '';
+        }
+
+        $precision = null;
+        $scale = null;
+
+        switch ($dbType) {
+            case 'char':
+                $fixed = true;
+                break;
+            case 'float':
+            case 'double':
+            case 'real':
+            case 'decimal':
+            case 'numeric':
+                if (isset($tableColumn['length'])) {
+                    list($precision, $scale) = array_map('trim', explode(', ', $tableColumn['length']));
+                }
+                $length = null;
+                break;
+        }
+
+        $options = array(
+            'length'   => $length,
+            'unsigned' => (bool) $unsigned,
+            'fixed'    => $fixed,
+            'notnull'  => $notnull,
+            'default'  => $default,
+            'precision' => $precision,
+            'scale'     => $scale,
+            'autoincrement' => false,
+        );
+
+        return new Column($tableColumn['name'], \Doctrine\DBAL\Types\Type::getType($type), $options);
+    }
+
+    protected function _getPortableViewDefinition($view)
+    {
+        return new View($view['name'], $view['sql']);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Table.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Table.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Table.php	(revision 345)
@@ -0,0 +1,645 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+use Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\Schema\Visitor\Visitor;
+use Doctrine\DBAL\DBALException;
+
+/**
+ * Object Representation of a table
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Table extends AbstractAsset
+{
+    /**
+     * @var string
+     */
+    protected $_name = null;
+
+    /**
+     * @var array
+     */
+    protected $_columns = array();
+
+    /**
+     * @var array
+     */
+    protected $_indexes = array();
+
+    /**
+     * @var string
+     */
+    protected $_primaryKeyName = false;
+
+    /**
+     * @var array
+     */
+    protected $_fkConstraints = array();
+
+    /**
+     * @var array
+     */
+    protected $_options = array();
+
+    /**
+     * @var SchemaConfig
+     */
+    protected $_schemaConfig = null;
+
+    /**
+     *
+     * @param string $tableName
+     * @param array $columns
+     * @param array $indexes
+     * @param array $fkConstraints
+     * @param int $idGeneratorType
+     * @param array $options
+     */
+    public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType = 0, array $options=array())
+    {
+        if (strlen($tableName) == 0) {
+            throw DBALException::invalidTableName($tableName);
+        }
+
+        $this->_setName($tableName);
+        $this->_idGeneratorType = $idGeneratorType;
+
+        foreach ($columns AS $column) {
+            $this->_addColumn($column);
+        }
+
+        foreach ($indexes AS $idx) {
+            $this->_addIndex($idx);
+        }
+
+        foreach ($fkConstraints AS $constraint) {
+            $this->_addForeignKeyConstraint($constraint);
+        }
+
+        $this->_options = $options;
+    }
+
+    /**
+     * @param SchemaConfig $schemaConfig
+     */
+    public function setSchemaConfig(SchemaConfig $schemaConfig)
+    {
+        $this->_schemaConfig = $schemaConfig;
+    }
+
+    /**
+     * @return int
+     */
+    protected function _getMaxIdentifierLength()
+    {
+        if ($this->_schemaConfig instanceof SchemaConfig) {
+            return $this->_schemaConfig->getMaxIdentifierLength();
+        } else {
+            return 63;
+        }
+    }
+
+    /**
+     * Set Primary Key
+     *
+     * @param array $columns
+     * @param string $indexName
+     * @return Table
+     */
+    public function setPrimaryKey(array $columns, $indexName = false)
+    {
+        $primaryKey = $this->_createIndex($columns, $indexName ?: "primary", true, true);
+
+        foreach ($columns AS $columnName) {
+            $column = $this->getColumn($columnName);
+            $column->setNotnull(true);
+        }
+
+        return $primaryKey;
+    }
+
+    /**
+     * @param array $columnNames
+     * @param string $indexName
+     * @return Table
+     */
+    public function addIndex(array $columnNames, $indexName = null)
+    {
+        if($indexName == null) {
+            $indexName = $this->_generateIdentifierName(
+                array_merge(array($this->getName()), $columnNames), "idx", $this->_getMaxIdentifierLength()
+            );
+        }
+
+        return $this->_createIndex($columnNames, $indexName, false, false);
+    }
+
+    /**
+     *
+     * @param array $columnNames
+     * @param string $indexName
+     * @return Table
+     */
+    public function addUniqueIndex(array $columnNames, $indexName = null)
+    {
+        if ($indexName === null) {
+            $indexName = $this->_generateIdentifierName(
+                array_merge(array($this->getName()), $columnNames), "uniq", $this->_getMaxIdentifierLength()
+            );
+        }
+
+        return $this->_createIndex($columnNames, $indexName, true, false);
+    }
+
+    /**
+     * Check if an index begins in the order of the given columns.
+     *
+     * @param  array $columnsNames
+     * @return bool
+     */
+    public function columnsAreIndexed(array $columnsNames)
+    {
+        foreach ($this->getIndexes() AS $index) {
+            /* @var $index Index */
+            if ($index->spansColumns($columnsNames)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     *
+     * @param array $columnNames
+     * @param string $indexName
+     * @param bool $isUnique
+     * @param bool $isPrimary
+     * @return Table
+     */
+    private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary)
+    {
+        if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) {
+            throw SchemaException::indexNameInvalid($indexName);
+        }
+
+        foreach ($columnNames AS $columnName => $indexColOptions) {
+            if (is_numeric($columnName) && is_string($indexColOptions)) {
+                $columnName = $indexColOptions;
+            }
+
+            if ( ! $this->hasColumn($columnName)) {
+                throw SchemaException::columnDoesNotExist($columnName, $this->_name);
+            }
+        }
+        $this->_addIndex(new Index($indexName, $columnNames, $isUnique, $isPrimary));
+        return $this;
+    }
+
+    /**
+     * @param string $columnName
+     * @param string $columnType
+     * @param array $options
+     * @return Column
+     */
+    public function addColumn($columnName, $typeName, array $options=array())
+    {
+        $column = new Column($columnName, Type::getType($typeName), $options);
+
+        $this->_addColumn($column);
+        return $column;
+    }
+
+    /**
+     * Rename Column
+     *
+     * @param string $oldColumnName
+     * @param string $newColumnName
+     * @return Table
+     */
+    public function renameColumn($oldColumnName, $newColumnName)
+    {
+        $column = $this->getColumn($oldColumnName);
+        $this->dropColumn($oldColumnName);
+
+        $column->_setName($newColumnName);
+        return $this;
+    }
+
+    /**
+     * Change Column Details
+     *
+     * @param string $columnName
+     * @param array $options
+     * @return Table
+     */
+    public function changeColumn($columnName, array $options)
+    {
+        $column = $this->getColumn($columnName);
+        $column->setOptions($options);
+        return $this;
+    }
+
+    /**
+     * Drop Column from Table
+     *
+     * @param string $columnName
+     * @return Table
+     */
+    public function dropColumn($columnName)
+    {
+        $columnName = strtolower($columnName);
+        $column = $this->getColumn($columnName);
+        unset($this->_columns[$columnName]);
+        return $this;
+    }
+
+
+    /**
+     * Add a foreign key constraint
+     *
+     * Name is inferred from the local columns
+     *
+     * @param Table $foreignTable
+     * @param array $localColumns
+     * @param array $foreignColumns
+     * @param array $options
+     * @param string $constraintName
+     * @return Table
+     */
+    public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array(), $constraintName = null)
+    {
+        $constraintName = $constraintName ?: $this->_generateIdentifierName(array_merge((array)$this->getName(), $localColumnNames), "fk", $this->_getMaxIdentifierLength());
+        return $this->addNamedForeignKeyConstraint($constraintName, $foreignTable, $localColumnNames, $foreignColumnNames, $options);
+    }
+
+    /**
+     * Add a foreign key constraint
+     *
+     * Name is to be generated by the database itsself.
+     *
+     * @deprecated Use {@link addForeignKeyConstraint}
+     * @param Table $foreignTable
+     * @param array $localColumns
+     * @param array $foreignColumns
+     * @param array $options
+     * @return Table
+     */
+    public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
+    {
+        return $this->addForeignKeyConstraint($foreignTable, $localColumnNames, $foreignColumnNames, $options);
+    }
+
+    /**
+     * Add a foreign key constraint with a given name
+     *
+     * @deprecated Use {@link addForeignKeyConstraint}
+     * @param string $name
+     * @param Table $foreignTable
+     * @param array $localColumns
+     * @param array $foreignColumns
+     * @param array $options
+     * @return Table
+     */
+    public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
+    {
+        if ($foreignTable instanceof Table) {
+            $foreignTableName = $foreignTable->getName();
+
+            foreach ($foreignColumnNames AS $columnName) {
+                if ( ! $foreignTable->hasColumn($columnName)) {
+                    throw SchemaException::columnDoesNotExist($columnName, $foreignTable->getName());
+                }
+            }
+        } else {
+            $foreignTableName = $foreignTable;
+        }
+
+        foreach ($localColumnNames AS $columnName) {
+            if ( ! $this->hasColumn($columnName)) {
+                throw SchemaException::columnDoesNotExist($columnName, $this->_name);
+            }
+        }
+
+        $constraint = new ForeignKeyConstraint(
+            $localColumnNames, $foreignTableName, $foreignColumnNames, $name, $options
+        );
+        $this->_addForeignKeyConstraint($constraint);
+
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     * @param string $value
+     * @return Table
+     */
+    public function addOption($name, $value)
+    {
+        $this->_options[$name] = $value;
+        return $this;
+    }
+
+    /**
+     * @param Column $column
+     */
+    protected function _addColumn(Column $column)
+    {
+        $columnName = $column->getName();
+        $columnName = strtolower($columnName);
+
+        if (isset($this->_columns[$columnName])) {
+            throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
+        }
+
+        $this->_columns[$columnName] = $column;
+    }
+
+    /**
+     * Add index to table
+     *
+     * @param Index $indexCandidate
+     * @return Table
+     */
+    protected function _addIndex(Index $indexCandidate)
+    {
+        // check for duplicates
+        foreach ($this->_indexes AS $existingIndex) {
+            if ($indexCandidate->isFullfilledBy($existingIndex)) {
+                return $this;
+            }
+        }
+
+        $indexName = $indexCandidate->getName();
+        $indexName = strtolower($indexName);
+
+        if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $indexCandidate->isPrimary())) {
+            throw SchemaException::indexAlreadyExists($indexName, $this->_name);
+        }
+
+        // remove overruled indexes
+        foreach ($this->_indexes AS $idxKey => $existingIndex) {
+            if ($indexCandidate->overrules($existingIndex)) {
+                unset($this->_indexes[$idxKey]);
+            }
+        }
+
+        if ($indexCandidate->isPrimary()) {
+            $this->_primaryKeyName = $indexName;
+        }
+
+        $this->_indexes[$indexName] = $indexCandidate;
+        return $this;
+    }
+
+    /**
+     * @param ForeignKeyConstraint $constraint
+     */
+    protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)
+    {
+        $constraint->setLocalTable($this);
+
+        if(strlen($constraint->getName())) {
+            $name = $constraint->getName();
+        } else {
+            $name = $this->_generateIdentifierName(
+                array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength()
+            );
+        }
+        $name = strtolower($name);
+
+        $this->_fkConstraints[$name] = $constraint;
+        // add an explicit index on the foreign key columns. If there is already an index that fullfils this requirements drop the request.
+        // In the case of __construct calling this method during hydration from schema-details all the explicitly added indexes
+        // lead to duplicates. This creates compuation overhead in this case, however no duplicate indexes are ever added (based on columns).
+        $this->addIndex($constraint->getColumns());
+    }
+
+    /**
+     * Does Table have a foreign key constraint with the given name?
+     *      *
+     * @param  string $constraintName
+     * @return bool
+     */
+    public function hasForeignKey($constraintName)
+    {
+        $constraintName = strtolower($constraintName);
+        return isset($this->_fkConstraints[$constraintName]);
+    }
+
+    /**
+     * @param string $constraintName
+     * @return ForeignKeyConstraint
+     */
+    public function getForeignKey($constraintName)
+    {
+        $constraintName = strtolower($constraintName);
+        if(!$this->hasForeignKey($constraintName)) {
+            throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
+        }
+
+        return $this->_fkConstraints[$constraintName];
+    }
+
+    public function removeForeignKey($constraintName)
+    {
+        $constraintName = strtolower($constraintName);
+        if(!$this->hasForeignKey($constraintName)) {
+            throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
+        }
+
+        unset($this->_fkConstraints[$constraintName]);
+    }
+
+    /**
+     * @return Column[]
+     */
+    public function getColumns()
+    {
+        $columns = $this->_columns;
+
+        $pkCols = array();
+        $fkCols = array();
+
+        if ($this->hasPrimaryKey()) {
+            $pkCols = $this->getPrimaryKey()->getColumns();
+        }
+        foreach ($this->getForeignKeys() AS $fk) {
+            /* @var $fk ForeignKeyConstraint */
+            $fkCols = array_merge($fkCols, $fk->getColumns());
+        }
+        $colNames = array_unique(array_merge($pkCols, $fkCols, array_keys($columns)));
+
+        uksort($columns, function($a, $b) use($colNames) {
+            return (array_search($a, $colNames) >= array_search($b, $colNames));
+        });
+        return $columns;
+    }
+
+
+    /**
+     * Does this table have a column with the given name?
+     *
+     * @param  string $columnName
+     * @return bool
+     */
+    public function hasColumn($columnName)
+    {
+        $columnName = $this->trimQuotes(strtolower($columnName));
+        return isset($this->_columns[$columnName]);
+    }
+
+    /**
+     * Get a column instance
+     *
+     * @param  string $columnName
+     * @return Column
+     */
+    public function getColumn($columnName)
+    {
+        $columnName = strtolower($this->trimQuotes($columnName));
+        if (!$this->hasColumn($columnName)) {
+            throw SchemaException::columnDoesNotExist($columnName, $this->_name);
+        }
+
+        return $this->_columns[$columnName];
+    }
+
+    /**
+     * @return Index|null
+     */
+    public function getPrimaryKey()
+    {
+        if (!$this->hasPrimaryKey()) {
+            return null;
+        }
+        return $this->getIndex($this->_primaryKeyName);
+    }
+
+    /**
+     * Check if this table has a primary key.
+     *
+     * @return bool
+     */
+    public function hasPrimaryKey()
+    {
+        return ($this->_primaryKeyName && $this->hasIndex($this->_primaryKeyName));
+    }
+
+    /**
+     * @param  string $indexName
+     * @return bool
+     */
+    public function hasIndex($indexName)
+    {
+        $indexName = strtolower($indexName);
+        return (isset($this->_indexes[$indexName]));
+    }
+
+    /**
+     * @param  string $indexName
+     * @return Index
+     */
+    public function getIndex($indexName)
+    {
+        $indexName = strtolower($indexName);
+        if (!$this->hasIndex($indexName)) {
+            throw SchemaException::indexDoesNotExist($indexName, $this->_name);
+        }
+        return $this->_indexes[$indexName];
+    }
+
+    /**
+     * @return array
+     */
+    public function getIndexes()
+    {
+        return $this->_indexes;
+    }
+
+    /**
+     * Get Constraints
+     *
+     * @return array
+     */
+    public function getForeignKeys()
+    {
+        return $this->_fkConstraints;
+    }
+
+    public function hasOption($name)
+    {
+        return isset($this->_options[$name]);
+    }
+
+    public function getOption($name)
+    {
+        return $this->_options[$name];
+    }
+
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * @param Visitor $visitor
+     */
+    public function visit(Visitor $visitor)
+    {
+        $visitor->acceptTable($this);
+
+        foreach ($this->getColumns() AS $column) {
+            $visitor->acceptColumn($this, $column);
+        }
+
+        foreach ($this->getIndexes() AS $index) {
+            $visitor->acceptIndex($this, $index);
+        }
+
+        foreach ($this->getForeignKeys() AS $constraint) {
+            $visitor->acceptForeignKey($this, $constraint);
+        }
+    }
+
+    /**
+     * Clone of a Table triggers a deep clone of all affected assets
+     */
+    public function __clone()
+    {
+        foreach ($this->_columns AS $k => $column) {
+            $this->_columns[$k] = clone $column;
+        }
+        foreach ($this->_indexes AS $k => $index) {
+            $this->_indexes[$k] = clone $index;
+        }
+        foreach ($this->_fkConstraints AS $k => $fk) {
+            $this->_fkConstraints[$k] = clone $fk;
+            $this->_fkConstraints[$k]->setLocalTable($this);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/TableDiff.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/TableDiff.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/TableDiff.php	(revision 345)
@@ -0,0 +1,136 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Table Diff
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class TableDiff
+{
+    /**
+     * @var string
+     */
+    public $name = null;
+
+    /**
+     * @var string
+     */
+    public $newName = false;
+
+    /**
+     * All added fields
+     *
+     * @var array(string=>Column)
+     */
+    public $addedColumns;
+
+    /**
+     * All changed fields
+     *
+     * @var array(string=>Column)
+     */
+    public $changedColumns = array();
+
+    /**
+     * All removed fields
+     *
+     * @var array(string=>Column)
+     */
+    public $removedColumns = array();
+
+    /**
+     * Columns that are only renamed from key to column instance name.
+     *
+     * @var array(string=>Column)
+     */
+    public $renamedColumns = array();
+
+    /**
+     * All added indexes
+     *
+     * @var array(string=>Index)
+     */
+    public $addedIndexes = array();
+
+    /**
+     * All changed indexes
+     *
+     * @var array(string=>Index)
+     */
+    public $changedIndexes = array();
+
+    /**
+     * All removed indexes
+     *
+     * @var array(string=>bool)
+     */
+    public $removedIndexes = array();
+
+    /**
+     * All added foreign key definitions
+     *
+     * @var array
+     */
+    public $addedForeignKeys = array();
+
+    /**
+     * All changed foreign keys
+     *
+     * @var array
+     */
+    public $changedForeignKeys = array();
+
+    /**
+     * All removed foreign keys
+     *
+     * @var array
+     */
+    public $removedForeignKeys = array();
+
+    /**
+     * Constructs an TableDiff object.
+     *
+     * @param array(string=>Column) $addedColumns
+     * @param array(string=>Column) $changedColumns
+     * @param array(string=>bool)   $removedColumns
+     * @param array(string=>Index)  $addedIndexes
+     * @param array(string=>Index)  $changedIndexes
+     * @param array(string=>bool)   $removedIndexes
+     */
+    public function __construct($tableName, $addedColumns = array(),
+        $changedColumns = array(), $removedColumns = array(), $addedIndexes = array(),
+        $changedIndexes = array(), $removedIndexes = array())
+    {
+        $this->name = $tableName;
+        $this->addedColumns = $addedColumns;
+        $this->changedColumns = $changedColumns;
+        $this->removedColumns = $removedColumns;
+        $this->addedIndexes = $addedIndexes;
+        $this->changedIndexes = $changedIndexes;
+        $this->removedIndexes = $removedIndexes;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/View.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/View.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/View.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Schema;
+
+/**
+ * Representation of a Database View
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class View extends AbstractAsset
+{
+    /**
+     * @var string
+     */
+    private $_sql;
+
+    public function __construct($name, $sql)
+    {
+        $this->_setName($name);
+        $this->_sql = $sql;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSql()
+    {
+        return $this->_sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php	(revision 345)
@@ -0,0 +1,147 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema\Visitor;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table,
+    Doctrine\DBAL\Schema\Schema,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\ForeignKeyConstraint,
+    Doctrine\DBAL\Schema\Constraint,
+    Doctrine\DBAL\Schema\Sequence,
+    Doctrine\DBAL\Schema\Index;
+
+class CreateSchemaSqlCollector implements Visitor
+{
+    /**
+     * @var array
+     */
+    private $_createTableQueries = array();
+
+    /**
+     * @var array
+     */
+    private $_createSequenceQueries = array();
+
+    /**
+     * @var array
+     */
+    private $_createFkConstraintQueries = array();
+
+    /**
+     *
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform = null;
+
+    /**
+     * @param AbstractPlatform $platform
+     */
+    public function __construct(AbstractPlatform $platform)
+    {
+        $this->_platform = $platform;
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function acceptSchema(Schema $schema)
+    {
+
+    }
+
+    /**
+     * Generate DDL Statements to create the accepted table with all its dependencies.
+     *
+     * @param Table $table
+     */
+    public function acceptTable(Table $table)
+    {
+        $this->_createTableQueries = array_merge($this->_createTableQueries,
+            $this->_platform->getCreateTableSQL($table)
+        );
+    }
+
+    public function acceptColumn(Table $table, Column $column)
+    {
+
+    }
+
+    /**
+     * @param Table $localTable
+     * @param ForeignKeyConstraint $fkConstraint
+     */
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
+    {
+        // Append the foreign key constraints SQL
+        if ($this->_platform->supportsForeignKeyConstraints()) {
+            $this->_createFkConstraintQueries = array_merge($this->_createFkConstraintQueries,
+                (array) $this->_platform->getCreateForeignKeySQL(
+                    $fkConstraint, $localTable
+                )
+            );
+        }
+    }
+
+    /**
+     * @param Table $table
+     * @param Index $index
+     */
+    public function acceptIndex(Table $table, Index $index)
+    {
+
+    }
+
+    /**
+     * @param Sequence $sequence
+     */
+    public function acceptSequence(Sequence $sequence)
+    {
+        $this->_createSequenceQueries = array_merge(
+            $this->_createSequenceQueries, (array)$this->_platform->getCreateSequenceSQL($sequence)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function resetQueries()
+    {
+        $this->_createTableQueries = array();
+        $this->_createSequenceQueries = array();
+        $this->_createFkConstraintQueries = array();
+    }
+
+    /**
+     * Get all queries collected so far.
+     *
+     * @return array
+     */
+    public function getQueries()
+    {
+        return array_merge(
+            $this->_createTableQueries,
+            $this->_createSequenceQueries,
+            $this->_createFkConstraintQueries
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php	(revision 345)
@@ -0,0 +1,159 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema\Visitor;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table,
+    Doctrine\DBAL\Schema\Schema,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\ForeignKeyConstraint,
+    Doctrine\DBAL\Schema\Constraint,
+    Doctrine\DBAL\Schema\Sequence,
+    Doctrine\DBAL\Schema\Index;
+
+/**
+ * Gather SQL statements that allow to completly drop the current schema.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DropSchemaSqlCollector implements Visitor
+{
+    /**
+     * @var \SplObjectStorage
+     */
+    private $constraints;
+
+    /**
+     * @var \SplObjectStorage
+     */
+    private $sequences;
+
+    /**
+     * @var \SplObjectStorage
+     */
+    private $tables;
+
+    /**
+     *
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $platform;
+
+    /**
+     * @param AbstractPlatform $platform
+     */
+    public function __construct(AbstractPlatform $platform)
+    {
+        $this->platform = $platform;
+        $this->clearQueries();
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function acceptSchema(Schema $schema)
+    {
+
+    }
+
+    /**
+     * @param Table $table
+     */
+    public function acceptTable(Table $table)
+    {
+        $this->tables->attach($table);
+    }
+
+    /**
+     * @param Column $column
+     */
+    public function acceptColumn(Table $table, Column $column)
+    {
+
+    }
+
+    /**
+     * @param Table $localTable
+     * @param ForeignKeyConstraint $fkConstraint
+     */
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
+    {
+        if (strlen($fkConstraint->getName()) == 0) {
+            throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint);
+        }
+
+        $this->constraints->attach($fkConstraint);
+        $this->constraints[$fkConstraint] = $localTable;
+    }
+
+    /**
+     * @param Table $table
+     * @param Index $index
+     */
+    public function acceptIndex(Table $table, Index $index)
+    {
+
+    }
+
+    /**
+     * @param Sequence $sequence
+     */
+    public function acceptSequence(Sequence $sequence)
+    {
+        $this->sequences->attach($sequence);
+    }
+
+    /**
+     * @return void
+     */
+    public function clearQueries()
+    {
+        $this->constraints = new \SplObjectStorage();
+        $this->sequences = new \SplObjectStorage();
+        $this->tables = new \SplObjectStorage();
+    }
+
+    /**
+     * @return array
+     */
+    public function getQueries()
+    {
+        $sql = array();
+        foreach ($this->constraints AS $fkConstraint) {
+            $localTable = $this->constraints[$fkConstraint];
+            $sql[] = $this->platform->getDropForeignKeySQL($fkConstraint, $localTable);
+        }
+
+        foreach ($this->sequences AS $sequence) {
+            $sql[] = $this->platform->getDropSequenceSQL($sequence);
+        }
+
+        foreach ($this->tables AS $table) {
+            $sql[] = $this->platform->getDropTableSQL($table);
+        }
+
+        return $sql;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Graphviz.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Graphviz.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Graphviz.php	(revision 345)
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema\Visitor;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+ Doctrine\DBAL\Schema\Table,
+ Doctrine\DBAL\Schema\Schema,
+ Doctrine\DBAL\Schema\Column,
+ Doctrine\DBAL\Schema\ForeignKeyConstraint,
+ Doctrine\DBAL\Schema\Constraint,
+ Doctrine\DBAL\Schema\Sequence,
+ Doctrine\DBAL\Schema\Index;
+
+class Graphviz implements \Doctrine\DBAL\Schema\Visitor\Visitor
+{
+    private $output = '';
+
+    public function acceptColumn(Table $table, Column $column)
+    {
+
+    }
+
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
+    {
+        $this->output .= $this->createNodeRelation(
+            $fkConstraint->getLocalTableName() . ":col" . current($fkConstraint->getLocalColumns()).":se",
+            $fkConstraint->getForeignTableName() . ":col" . current($fkConstraint->getForeignColumns()).":se",
+            array(
+                'dir'       => 'back',
+                'arrowtail' => 'dot',
+                'arrowhead' => 'normal',
+            )
+        );
+    }
+
+    public function acceptIndex(Table $table, Index $index)
+    {
+
+    }
+
+    public function acceptSchema(Schema $schema)
+    {
+        $this->output  = 'digraph "' . sha1( mt_rand() ) . '" {' . "\n";
+        $this->output .= 'splines = true;' . "\n";
+        $this->output .= 'overlap = false;' . "\n";
+        $this->output .= 'outputorder=edgesfirst;'."\n";
+        $this->output .= 'mindist = 0.6;' . "\n";
+        $this->output .= 'sep = .2;' . "\n";
+    }
+
+    public function acceptSequence(Sequence $sequence)
+    {
+
+    }
+
+    public function acceptTable(Table $table)
+    {
+        $this->output .= $this->createNode(
+            $table->getName(),
+            array(
+                'label' => $this->createTableLabel( $table ),
+                'shape' => 'plaintext',
+            )
+        );
+    }
+
+    private function createTableLabel( Table $table )
+    {
+        // Start the table
+        $label = '<<TABLE CELLSPACING="0" BORDER="1" ALIGN="LEFT">';
+
+        // The title
+        $label .= '<TR><TD BORDER="1" COLSPAN="3" ALIGN="CENTER" BGCOLOR="#fcaf3e"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $table->getName() . '</FONT></TD></TR>';
+
+        // The attributes block
+        foreach( $table->getColumns() as $column ) {
+            $columnLabel = $column->getName();
+
+            $label .= '<TR>';
+            $label .= '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">';
+            $label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>';
+            $label .= '</TD><TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()) . '</FONT></TD>';
+            $label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col'.$column->getName().'">';
+            if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) {
+                $label .= "\xe2\x9c\xb7";
+            }
+            $label .= '</TD></TR>';
+        }
+
+        // End the table
+        $label .= '</TABLE>>';
+
+        return $label;
+    }
+
+    private function createNode( $name, $options )
+    {
+        $node = $name . " [";
+        foreach( $options as $key => $value )
+        {
+            $node .= $key . '=' . $value . ' ';
+        }
+        $node .= "]\n";
+        return $node;
+    }
+
+    private function createNodeRelation( $node1, $node2, $options )
+    {
+        $relation = $node1 . ' -> ' . $node2 . ' [';
+        foreach( $options as $key => $value )
+        {
+            $relation .= $key . '=' . $value . ' ';
+        }
+        $relation .= "]\n";
+        return $relation;
+    }
+
+    /**
+     * Write dot language output to a file. This should usually be a *.dot file.
+     *
+     * You have to convert the output into a viewable format. For example use "neato" on linux systems
+     * and execute:
+     *
+     *  neato -Tpng -o er.png er.dot
+     *
+     * @param string $filename
+     * @return void
+     */
+    public function write($filename)
+    {
+        file_put_contents($filename, $this->output . "}");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema\Visitor;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table,
+    Doctrine\DBAL\Schema\Schema,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\ForeignKeyConstraint,
+    Doctrine\DBAL\Schema\Constraint,
+    Doctrine\DBAL\Schema\Sequence,
+    Doctrine\DBAL\Schema\Index;
+
+/**
+ * Remove assets from a schema that are not in the default namespace.
+ *
+ * Some databases such as MySQL support cross databases joins, but don't
+ * allow to call DDLs to a database from another connected database.
+ * Before a schema is serialized into SQL this visitor can cleanup schemas with
+ * non default namespaces.
+ *
+ * This visitor filters all these non-default namespaced tables and sequences
+ * and removes them from the SChema instance.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.2
+ */
+class RemoveNamespacedAssets implements Visitor
+{
+    /**
+     * @var Schema
+     */
+    private $schema;
+
+    /**
+     * @param Schema $schema
+     */
+    public function acceptSchema(Schema $schema)
+    {
+        $this->schema = $schema;
+    }
+
+    /**
+     * @param Table $table
+     */
+    public function acceptTable(Table $table)
+    {
+        if ( ! $table->isInDefaultNamespace($this->schema->getName()) ) {
+            $this->schema->dropTable($table->getName());
+        }
+    }
+    /**
+     * @param Sequence $sequence
+     */
+    public function acceptSequence(Sequence $sequence)
+    {
+        if ( ! $sequence->isInDefaultNamespace($this->schema->getName()) ) {
+            $this->schema->dropSequence($sequence->getName());
+        }
+    }
+
+    /**
+     * @param Column $column
+     */
+    public function acceptColumn(Table $table, Column $column)
+    {
+    }
+
+    /**
+     * @param Table $localTable
+     * @param ForeignKeyConstraint $fkConstraint
+     */
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
+    {
+        // The table may already be deleted in a previous
+        // RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that
+        // point to nowhere.
+        if ( ! $this->schema->hasTable($fkConstraint->getForeignTableName())) {
+            $localTable->removeForeignKey($fkConstraint->getName());
+            return;
+        }
+
+        $foreignTable = $this->schema->getTable($fkConstraint->getForeignTableName());
+        if ( ! $foreignTable->isInDefaultNamespace($this->schema->getName()) ) {
+            $localTable->removeForeignKey($fkConstraint->getName());
+        }
+    }
+
+    /**
+     * @param Table $table
+     * @param Index $index
+     */
+    public function acceptIndex(Table $table, Index $index)
+    {
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Visitor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Visitor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Schema/Visitor/Visitor.php	(revision 345)
@@ -0,0 +1,75 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Schema\Visitor;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\Schema\Table,
+    Doctrine\DBAL\Schema\Schema,
+    Doctrine\DBAL\Schema\Column,
+    Doctrine\DBAL\Schema\ForeignKeyConstraint,
+    Doctrine\DBAL\Schema\Constraint,
+    Doctrine\DBAL\Schema\Sequence,
+    Doctrine\DBAL\Schema\Index;
+
+/**
+ * Schema Visitor used for Validation or Generation purposes.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface Visitor
+{
+    /**
+     * @param Schema $schema
+     */
+    public function acceptSchema(Schema $schema);
+
+    /**
+     * @param Table $table
+     */
+    public function acceptTable(Table $table);
+
+    /**
+     * @param Column $column
+     */
+    public function acceptColumn(Table $table, Column $column);
+
+    /**
+     * @param Table $localTable
+     * @param ForeignKeyConstraint $fkConstraint
+     */
+    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint);
+
+    /**
+     * @param Table $table
+     * @param Index $index
+     */
+    public function acceptIndex(Table $table, Index $index);
+
+    /**
+     * @param Sequence $sequence
+     */
+    public function acceptSequence(Sequence $sequence);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Statement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Statement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Statement.php	(revision 345)
@@ -0,0 +1,247 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use PDO,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Driver\Statement as DriverStatement;
+
+/**
+ * A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support
+ * for logging, DBAL mapping types, etc.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class Statement implements \IteratorAggregate, DriverStatement
+{
+    /**
+     * @var string The SQL statement.
+     */
+    protected $sql;
+    /**
+     * @var array The bound parameters.
+     */
+    protected $params = array();
+    /**
+     * @var Doctrine\DBAL\Driver\Statement The underlying driver statement.
+     */
+    protected $stmt;
+    /**
+     * @var Doctrine\DBAL\Platforms\AbstractPlatform The underlying database platform.
+     */
+    protected $platform;
+    /**
+     * @var Doctrine\DBAL\Connection The connection this statement is bound to and executed on.
+     */
+    protected $conn;
+
+    /**
+     * Creates a new <tt>Statement</tt> for the given SQL and <tt>Connection</tt>.
+     *
+     * @param string $sql The SQL of the statement.
+     * @param Doctrine\DBAL\Connection The connection on which the statement should be executed.
+     */
+    public function __construct($sql, Connection $conn)
+    {
+        $this->sql = $sql;
+        $this->stmt = $conn->getWrappedConnection()->prepare($sql);
+        $this->conn = $conn;
+        $this->platform = $conn->getDatabasePlatform();
+    }
+
+    /**
+     * Binds a parameter value to the statement.
+     *
+     * The value can optionally be bound with a PDO binding type or a DBAL mapping type.
+     * If bound with a DBAL mapping type, the binding type is derived from the mapping
+     * type and the value undergoes the conversion routines of the mapping type before
+     * being bound.
+     *
+     * @param $name The name or position of the parameter.
+     * @param $value The value of the parameter.
+     * @param mixed $type Either a PDO binding type or a DBAL mapping type name or instance.
+     * @return boolean TRUE on success, FALSE on failure.
+     */
+    public function bindValue($name, $value, $type = null)
+    {
+        $this->params[$name] = $value;
+        if ($type !== null) {
+            if (is_string($type)) {
+                $type = Type::getType($type);
+            }
+            if ($type instanceof Type) {
+                $value = $type->convertToDatabaseValue($value, $this->platform);
+                $bindingType = $type->getBindingType();
+            } else {
+                $bindingType = $type; // PDO::PARAM_* constants
+            }
+            return $this->stmt->bindValue($name, $value, $bindingType);
+        } else {
+            return $this->stmt->bindValue($name, $value);
+        }
+    }
+
+    /**
+     * Binds a parameter to a value by reference.
+     *
+     * Binding a parameter by reference does not support DBAL mapping types.
+     *
+     * @param string $name The name or position of the parameter.
+     * @param mixed $value The reference to the variable to bind
+     * @param integer $type The PDO binding type.
+     * @return boolean TRUE on success, FALSE on failure.
+     */
+    public function bindParam($name, &$var, $type = PDO::PARAM_STR)
+    {
+        return $this->stmt->bindParam($name, $var, $type);
+    }
+
+    /**
+     * Executes the statement with the currently bound parameters.
+     *
+     * @return boolean TRUE on success, FALSE on failure.
+     */
+    public function execute($params = null)
+    {
+        $hasLogger = $this->conn->getConfiguration()->getSQLLogger();
+        if ($hasLogger) {
+            $this->conn->getConfiguration()->getSQLLogger()->startQuery($this->sql, $this->params);
+        }
+
+        $stmt = $this->stmt->execute($params);
+
+        if ($hasLogger) {
+            $this->conn->getConfiguration()->getSQLLogger()->stopQuery();
+        }
+        $this->params = array();
+        return $stmt;
+    }
+
+    /**
+     * Closes the cursor, freeing the database resources used by this statement.
+     *
+     * @return boolean TRUE on success, FALSE on failure.
+     */
+    public function closeCursor()
+    {
+        return $this->stmt->closeCursor();
+    }
+
+    /**
+     * Returns the number of columns in the result set.
+     *
+     * @return integer
+     */
+    public function columnCount()
+    {
+        return $this->stmt->columnCount();
+    }
+
+    /**
+     * Fetches the SQLSTATE associated with the last operation on the statement.
+     *
+     * @return string
+     */
+    public function errorCode()
+    {
+        return $this->stmt->errorCode();
+    }
+
+    /**
+     * Fetches extended error information associated with the last operation on the statement.
+     *
+     * @return array
+     */
+    public function errorInfo()
+    {
+        return $this->stmt->errorInfo();
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        return $this->stmt->setFetchMode($fetchStyle);
+    }
+
+    public function getIterator()
+    {
+        return $this->stmt;
+    }
+
+    /**
+     * Fetches the next row from a result set.
+     *
+     * @param integer $fetchStyle
+     * @return mixed The return value of this function on success depends on the fetch type.
+     *               In all cases, FALSE is returned on failure.
+     */
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        return $this->stmt->fetch($fetchStyle);
+    }
+
+    /**
+     * Returns an array containing all of the result set rows.
+     *
+     * @param integer $fetchStyle
+     * @param mixed $fetchArgument
+     * @return array An array containing all of the remaining rows in the result set.
+     */
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH, $fetchArgument = 0)
+    {
+        if ($fetchArgument !== 0) {
+            return $this->stmt->fetchAll($fetchStyle, $fetchArgument);
+        }
+        return $this->stmt->fetchAll($fetchStyle);
+    }
+
+    /**
+     * Returns a single column from the next row of a result set.
+     *
+     * @param integer $columnIndex
+     * @return mixed A single column from the next row of a result set or FALSE if there are no more rows.
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        return $this->stmt->fetchColumn($columnIndex);
+    }
+
+    /**
+     * Returns the number of rows affected by the last execution of this statement.
+     *
+     * @return integer The number of affected rows.
+     */
+    public function rowCount()
+    {
+        return $this->stmt->rowCount();
+    }
+
+    /**
+     * Gets the wrapped driver statement.
+     *
+     * @return Doctrine\DBAL\Driver\Statement
+     */
+    public function getWrappedStatement()
+    {
+        return $this->stmt;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php	(revision 345)
@@ -0,0 +1,124 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console;
+
+/**
+ * Task for executing arbitrary SQL that can come from a file or directly from
+ * the command line.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ImportCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('dbal:import')
+        ->setDescription('Import SQL file(s) directly to Database.')
+        ->setDefinition(array(
+            new InputArgument(
+                'file', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'File path(s) of SQL to be executed.'
+            )
+        ))
+        ->setHelp(<<<EOT
+Import SQL file(s) directly to Database.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $conn = $this->getHelper('db')->getConnection();
+
+        if (($fileNames = $input->getArgument('file')) !== null)  {
+            foreach ((array) $fileNames as $fileName) {
+                $fileName = realpath($fileName);
+
+                if ( ! file_exists($fileName)) {
+                    throw new \InvalidArgumentException(
+                        sprintf("SQL file '<info>%s</info>' does not exist.", $fileName)
+                    );
+                } else if ( ! is_readable($fileName)) {
+                    throw new \InvalidArgumentException(
+                        sprintf("SQL file '<info>%s</info>' does not have read permissions.", $fileName)
+                    );
+                }
+
+                $output->write(sprintf("Processing file '<info>%s</info>'... ", $fileName));
+                $sql = file_get_contents($fileName);
+
+                if ($conn instanceof \Doctrine\DBAL\Driver\PDOConnection) {
+                    // PDO Drivers
+                    try {
+                        $lines = 0;
+
+                        $stmt = $conn->prepare($sql);
+                        $stmt->execute();
+
+                        do {
+                            // Required due to "MySQL has gone away!" issue
+                            $stmt->fetch();
+                            $stmt->closeCursor();
+
+                            $lines++;
+                        } while ($stmt->nextRowset());
+
+                        $output->write(sprintf('%d statements executed!', $lines) . PHP_EOL);
+                    } catch (\PDOException $e) {
+                        $output->write('error!' . PHP_EOL);
+
+                        throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
+                    }
+                } else {
+                    // Non-PDO Drivers (ie. OCI8 driver)
+                    $stmt = $conn->prepare($sql);
+                    $rs = $stmt->execute();
+
+                    if ($rs) {
+                        $output->writeln('OK!' . PHP_EOL);
+                    } else {
+                        $error = $stmt->errorInfo();
+
+                        $output->write('error!' . PHP_EOL);
+
+                        throw new \RuntimeException($error[2], $error[0]);
+                    }
+
+                    $stmt->closeCursor();
+                }
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php	(revision 345)
@@ -0,0 +1,133 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console\Command\Command,
+    Symfony\Component\Console\Input\InputInterface,
+    Symfony\Component\Console\Output\OutputInterface;
+use Doctrine\DBAL\Platforms\Keywords\ReservedKeywordsValidator;
+
+class ReservedWordsCommand extends Command
+{
+    private $keywordListClasses = array(
+        'mysql'     => 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords',
+        'mssql'     => 'Doctrine\DBAL\Platforms\Keywords\MsSQLKeywords',
+        'sqlite'    => 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords',
+        'pgsql'     => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords',
+        'oracle'    => 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords',
+        'db2'       => 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords',
+    );
+
+    /**
+     * If you want to add or replace a keywords list use this command
+     *
+     * @param string $name
+     * @param string $class
+     */
+    public function setKeywordListClass($name, $class)
+    {
+        $this->keywordListClasses[$name] = $class;
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('dbal:reserved-words')
+        ->setDescription('Checks if the current database contains identifiers that are reserved.')
+        ->setDefinition(array(
+            new InputOption(
+                'list', 'l', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Keyword-List name.'
+            )
+        ))
+        ->setHelp(<<<EOT
+Checks if the current database contains tables and columns
+with names that are identifiers in this dialect or in other SQL dialects.
+
+By default SQLite, MySQL, PostgreSQL, MsSQL and Oracle
+keywords are checked:
+
+    <info>doctrine dbal:reserved-words</info>
+
+If you want to check against specific dialects you can
+pass them to the command:
+
+    <info>doctrine dbal:reserved-words mysql pgsql</info>
+
+The following keyword lists are currently shipped with Doctrine:
+
+    * mysql
+    * pgsql
+    * sqlite
+    * oracle
+    * mssql
+    * db2 (Not checked by default)
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        /* @var $conn Doctrine\DBAL\Connection */
+        $conn = $this->getHelper('db')->getConnection();
+
+        $keywordLists = (array)$input->getOption('list');
+        if (!$keywordLists) {
+            $keywordLists = array('mysql', 'pgsql', 'sqlite', 'oracle', 'mssql');
+        }
+
+        $keywords = array();
+        foreach ($keywordLists AS $keywordList) {
+            if (!isset($this->keywordListClasses[$keywordList])) {
+                throw new \InvalidArgumentException(
+                    "There exists no keyword list with name '" . $keywordList . "'. ".
+                    "Known lists: " . implode(", ", array_keys($this->keywordListClasses))
+                );
+            }
+            $class = $this->keywordListClasses[$keywordList];
+            $keywords[] = new $class;
+        }
+
+        $output->write('Checking keyword violations for <comment>' . implode(", ", $keywordLists) . "</comment>...", true);
+
+        /* @var $schema \Doctrine\DBAL\Schema\Schema */
+        $schema = $conn->getSchemaManager()->createSchema();
+        $visitor = new ReservedKeywordsValidator($keywords);
+        $schema->visit($visitor);
+
+        $violations = $visitor->getViolations();
+        if (count($violations) == 0) {
+            $output->write("No reserved keywords violations have been found!", true);
+        } else {
+            $output->write('There are <error>' . count($violations) . '</error> reserved keyword violations in your database schema:', true);
+            foreach ($violations AS $violation) {
+                $output->write('  - ' . $violation, true);
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php	(revision 345)
@@ -0,0 +1,87 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console;
+
+/**
+ * Task for executing arbitrary SQL that can come from a file or directly from
+ * the command line.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class RunSqlCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('dbal:run-sql')
+        ->setDescription('Executes arbitrary SQL directly from the command line.')
+        ->setDefinition(array(
+            new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'),
+            new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', 7)
+        ))
+        ->setHelp(<<<EOT
+Executes arbitrary SQL directly from the command line.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $conn = $this->getHelper('db')->getConnection();
+
+        if (($sql = $input->getArgument('sql')) === null) {
+            throw new \RuntimeException("Argument 'SQL' is required in order to execute this command correctly.");
+        }
+
+        $depth = $input->getOption('depth');
+
+        if ( ! is_numeric($depth)) {
+            throw new \LogicException("Option 'depth' must contains an integer value");
+        }
+
+        if (preg_match('/^select/i', $sql)) {
+           $resultSet = $conn->fetchAll($sql);
+        } else {
+            $resultSet = $conn->executeUpdate($sql);
+        }
+
+        ob_start();
+        \Doctrine\Common\Util\Debug::dump($resultSet, (int) $depth);
+        $message = ob_get_clean();
+
+        $output->write($message);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php	(revision 345)
@@ -0,0 +1,74 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Tools\Console\Helper;
+
+use Symfony\Component\Console\Helper\Helper,
+    Doctrine\DBAL\Connection;
+
+/**
+ * Doctrine CLI Connection Helper.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConnectionHelper extends Helper
+{
+    /**
+     * Doctrine Database Connection
+     * @var Connection
+     */
+    protected $_connection;
+
+    /**
+     * Constructor
+     *
+     * @param Connection $connection Doctrine Database Connection
+     */
+    public function __construct(Connection $connection)
+    {
+        $this->_connection = $connection;
+    }
+
+    /**
+     * Retrieves Doctrine Database Connection
+     *
+     * @return Connection
+     */
+    public function getConnection()
+    {
+        return $this->_connection;
+    }
+
+    /**
+     * @see Helper
+     */
+    public function getName()
+    {
+        return 'connection';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ArrayType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ArrayType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ArrayType.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+/**
+ * Type that maps a PHP array to a clob SQL type.
+ *
+ * @since 2.0
+ */
+class ArrayType extends Type
+{
+    public function getSQLDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        return $platform->getClobTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        return serialize($value);
+    }
+
+    public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $value = (is_resource($value)) ? stream_get_contents($value) : $value;
+        $val = unserialize($value);
+        if ($val === false && $value != 'b:0;') {
+            throw ConversionException::conversionFailed($value, $this->getName());
+        }
+        return $val;
+    }
+
+    public function getName()
+    {
+        return Type::TARRAY;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BigIntType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BigIntType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BigIntType.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps a database BIGINT to a PHP string.
+ *
+ * @author robo
+ * @since 2.0
+ */
+class BigIntType extends Type
+{
+    public function getName()
+    {
+        return Type::BIGINT;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getBigIntTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function getBindingType()
+    {
+        return \PDO::PARAM_STR;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BlobType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BlobType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BlobType.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL BLOB to a PHP resource stream
+ *
+ * @since 2.2
+ */
+class BlobType extends Type
+{
+    /** @override */
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getBlobTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    /**
+     * Converts a value from its database representation to its PHP representation
+     * of this type.
+     *
+     * @param mixed $value The value to convert.
+     * @param AbstractPlatform $platform The currently used database platform.
+     * @return mixed The PHP representation of the value.
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if (null === $value) {
+            return null;
+        }
+        if (is_string($value)) {
+            $value = fopen('data://text/plain;base64,' . base64_encode($value), 'r');
+        } else if ( ! is_resource($value)) {
+            throw ConversionException::conversionFailed($value, self::BLOB);
+        }
+        return $value;
+    }
+
+    public function getName()
+    {
+        return Type::BLOB;
+    }
+
+    public function getBindingType()
+    {
+        return \PDO::PARAM_LOB;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BooleanType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BooleanType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/BooleanType.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL boolean to a PHP boolean.
+ *
+ * @since 2.0
+ */
+class BooleanType extends Type
+{
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getBooleanTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return $platform->convertBooleans($value);
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (null === $value) ? null : (bool) $value;
+    }
+
+    public function getName()
+    {
+        return Type::BOOLEAN;
+    }
+
+    public function getBindingType()
+    {
+        return \PDO::PARAM_BOOL;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ConversionException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ConversionException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ConversionException.php	(revision 345)
@@ -0,0 +1,65 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+/**
+ * Conversion Exception is thrown when the database to PHP conversion fails
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+namespace Doctrine\DBAL\Types;
+
+class ConversionException extends \Doctrine\DBAL\DBALException
+{
+    /**
+     * Thrown when a Database to Doctrine Type Conversion fails.
+     *
+     * @param  string $value
+     * @param  string $toType
+     * @return ConversionException
+     */
+    static public function conversionFailed($value, $toType)
+    {
+        $value = (strlen($value) > 32) ? substr($value, 0, 20) . "..." : $value;
+        return new self('Could not convert database value "' . $value . '" to Doctrine Type ' . $toType);
+    }
+
+    /**
+     * Thrown when a Database to Doctrine Type Conversion fails and we can make a statement
+     * about the expected format.
+     *
+     * @param  string $value
+     * @param  string $toType
+     * @return ConversionException
+     */
+    static public function conversionFailedFormat($value, $toType, $expectedFormat)
+    {
+        $value = (strlen($value) > 32) ? substr($value, 0, 20) . "..." : $value;
+        return new self(
+            'Could not convert database value "' . $value . '" to Doctrine Type ' .
+            $toType . '. Expected format: ' . $expectedFormat
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeType.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL DATETIME/TIMESTAMP to a PHP DateTime object.
+ *
+ * @since 2.0
+ */
+class DateTimeType extends Type
+{
+    public function getName()
+    {
+        return Type::DATETIME;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getDateTimeTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return ($value !== null)
+            ? $value->format($platform->getDateTimeFormatString()) : null;
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $val = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
+        if (!$val) {
+            throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString());
+        }
+        return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeTzType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeTzType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateTimeTzType.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * DateTime type saving additional timezone information.
+ *
+ * Caution: Databases are not necessarily experts at storing timezone related
+ * data of dates. First, of all the supported vendors only PostgreSQL and Oracle
+ * support storing Timezone data. But those two don't save the actual timezone
+ * attached to a DateTime instance (for example "Europe/Berlin" or "America/Montreal")
+ * but the current offset of them related to UTC. That means depending on daylight saving times
+ * or not you may get different offsets.
+ *
+ * This datatype makes only sense to use, if your application works with an offset, not
+ * with an actual timezone that uses transitions. Otherwise your DateTime instance
+ * attached with a timezone such as Europe/Berlin gets saved into the database with
+ * the offset and re-created from persistence with only the offset, not the original timezone
+ * attached.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class DateTimeTzType extends Type
+{
+    public function getName()
+    {
+        return Type::DATETIMETZ;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getDateTimeTzTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return ($value !== null)
+            ? $value->format($platform->getDateTimeTzFormatString()) : null;
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $val = \DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value);
+        if (!$val) {
+            throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeTzFormatString());
+        }
+        return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DateType.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL DATE to a PHP Date object.
+ *
+ * @since 2.0
+ */
+class DateType extends Type
+{
+    public function getName()
+    {
+        return Type::DATE;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getDateTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return ($value !== null)
+            ? $value->format($platform->getDateFormatString()) : null;
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $val = \DateTime::createFromFormat('!'.$platform->getDateFormatString(), $value);
+        if (!$val) {
+            throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateFormatString());
+        }
+        return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DecimalType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DecimalType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/DecimalType.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL DECIMAL to a PHP double.
+ *
+ * @since 2.0
+ */
+class DecimalType extends Type
+{
+    public function getName()
+    {
+        return Type::DECIMAL;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getDecimalTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (null === $value) ? null : $value;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/FloatType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/FloatType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/FloatType.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+class FloatType extends Type
+{
+    public function getName()
+    {
+        return Type::FLOAT;
+    }
+
+    /**
+     * @param array $fieldDeclaration
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getFloatDeclarationSQL($fieldDeclaration);
+    }
+
+    /**
+     * Converts a value from its database representation to its PHP representation
+     * of this type.
+     *
+     * @param mixed $value The value to convert.
+     * @param AbstractPlatform $platform The currently used database platform.
+     * @return mixed The PHP representation of the value.
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (null === $value) ? null : (double) $value;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/IntegerType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/IntegerType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/IntegerType.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL INT to a PHP integer.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class IntegerType extends Type
+{
+    public function getName()
+    {
+        return Type::INTEGER;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getIntegerTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (null === $value) ? null : (int) $value;
+    }
+
+    public function getBindingType()
+    {
+        return \PDO::PARAM_INT;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ObjectType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ObjectType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/ObjectType.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+/**
+ * Type that maps a PHP object to a clob SQL type.
+ *
+ * @since 2.0
+ */
+class ObjectType extends Type
+{
+    public function getSQLDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        return $platform->getClobTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        return serialize($value);
+    }
+
+    public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $value = (is_resource($value)) ? stream_get_contents($value) : $value;
+        $val = unserialize($value);
+        if ($val === false && $value !== 'b:0;') {
+            throw ConversionException::conversionFailed($value, $this->getName());
+        }
+        return $val;
+    }
+
+    public function getName()
+    {
+        return Type::OBJECT;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/SmallIntType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/SmallIntType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/SmallIntType.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps a database SMALLINT to a PHP integer.
+ *
+ * @author robo
+ */
+class SmallIntType extends Type
+{
+    public function getName()
+    {
+        return Type::SMALLINT;
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (null === $value) ? null : (int) $value;
+    }
+
+    public function getBindingType()
+    {
+        return \PDO::PARAM_INT;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/StringType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/StringType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/StringType.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL VARCHAR to a PHP string.
+ *
+ * @since 2.0
+ */
+class StringType extends Type
+{
+    /** @override */
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    /** @override */
+    public function getDefaultLength(AbstractPlatform $platform)
+    {
+        return $platform->getVarcharDefaultLength();
+    }
+
+    /** @override */
+    public function getName()
+    {
+        return Type::STRING;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TextType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TextType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TextType.php	(revision 345)
@@ -0,0 +1,56 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL CLOB to a PHP string.
+ *
+ * @since 2.0
+ */
+class TextType extends Type
+{
+    /** @override */
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getClobTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    /**
+     * Converts a value from its database representation to its PHP representation
+     * of this type.
+     *
+     * @param mixed $value The value to convert.
+     * @param AbstractPlatform $platform The currently used database platform.
+     * @return mixed The PHP representation of the value.
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return (is_resource($value)) ? stream_get_contents($value) : $value;
+    }
+
+    public function getName()
+    {
+        return Type::TEXT;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TimeType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TimeType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/TimeType.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Type that maps an SQL TIME to a PHP DateTime object.
+ *
+ * @since 2.0
+ */
+class TimeType extends Type
+{
+    public function getName()
+    {
+        return Type::TIME;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return $platform->getTimeTypeDeclarationSQL($fieldDeclaration);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return ($value !== null)
+            ? $value->format($platform->getTimeFormatString()) : null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $val = \DateTime::createFromFormat($platform->getTimeFormatString(), $value);
+        if (!$val) {
+            throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString());
+        }
+        return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/Type.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/Type.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/Type.php	(revision 345)
@@ -0,0 +1,274 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform,
+    Doctrine\DBAL\DBALException;
+
+/**
+ * The base class for so-called Doctrine mapping types.
+ *
+ * A Type object is obtained by calling the static {@link getType()} method.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.0
+ */
+abstract class Type
+{
+    const TARRAY = 'array';
+    const BIGINT = 'bigint';
+    const BOOLEAN = 'boolean';
+    const DATETIME = 'datetime';
+    const DATETIMETZ = 'datetimetz';
+    const DATE = 'date';
+    const TIME = 'time';
+    const DECIMAL = 'decimal';
+    const INTEGER = 'integer';
+    const OBJECT = 'object';
+    const SMALLINT = 'smallint';
+    const STRING = 'string';
+    const TEXT = 'text';
+    const BLOB = 'blob';
+    const FLOAT = 'float';
+
+    /** Map of already instantiated type objects. One instance per type (flyweight). */
+    private static $_typeObjects = array();
+
+    /** The map of supported doctrine mapping types. */
+    private static $_typesMap = array(
+        self::TARRAY => 'Doctrine\DBAL\Types\ArrayType',
+        self::OBJECT => 'Doctrine\DBAL\Types\ObjectType',
+        self::BOOLEAN => 'Doctrine\DBAL\Types\BooleanType',
+        self::INTEGER => 'Doctrine\DBAL\Types\IntegerType',
+        self::SMALLINT => 'Doctrine\DBAL\Types\SmallIntType',
+        self::BIGINT => 'Doctrine\DBAL\Types\BigIntType',
+        self::STRING => 'Doctrine\DBAL\Types\StringType',
+        self::TEXT => 'Doctrine\DBAL\Types\TextType',
+        self::DATETIME => 'Doctrine\DBAL\Types\DateTimeType',
+        self::DATETIMETZ => 'Doctrine\DBAL\Types\DateTimeTzType',
+        self::DATE => 'Doctrine\DBAL\Types\DateType',
+        self::TIME => 'Doctrine\DBAL\Types\TimeType',
+        self::DECIMAL => 'Doctrine\DBAL\Types\DecimalType',
+        self::FLOAT => 'Doctrine\DBAL\Types\FloatType',
+        self::BLOB => 'Doctrine\DBAL\Types\BlobType',
+    );
+
+    /* Prevent instantiation and force use of the factory method. */
+    final private function __construct() {}
+
+    /**
+     * Converts a value from its PHP representation to its database representation
+     * of this type.
+     *
+     * @param mixed $value The value to convert.
+     * @param AbstractPlatform $platform The currently used database platform.
+     * @return mixed The database representation of the value.
+     */
+    public function convertToDatabaseValue($value, AbstractPlatform $platform)
+    {
+        return $value;
+    }
+
+    /**
+     * Converts a value from its database representation to its PHP representation
+     * of this type.
+     *
+     * @param mixed $value The value to convert.
+     * @param AbstractPlatform $platform The currently used database platform.
+     * @return mixed The PHP representation of the value.
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        return $value;
+    }
+
+    /**
+     * Gets the default length of this type.
+     *
+     * @todo Needed?
+     */
+    public function getDefaultLength(AbstractPlatform $platform)
+    {
+        return null;
+    }
+
+    /**
+     * Gets the SQL declaration snippet for a field of this type.
+     *
+     * @param array $fieldDeclaration The field declaration.
+     * @param AbstractPlatform $platform The currently used database platform.
+     */
+    abstract public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
+
+    /**
+     * Gets the name of this type.
+     *
+     * @return string
+     * @todo Needed?
+     */
+    abstract public function getName();
+
+    /**
+     * Factory method to create type instances.
+     * Type instances are implemented as flyweights.
+     *
+     * @static
+     * @throws DBALException
+     * @param string $name The name of the type (as returned by getName()).
+     * @return Doctrine\DBAL\Types\Type
+     */
+    public static function getType($name)
+    {
+        if ( ! isset(self::$_typeObjects[$name])) {
+            if ( ! isset(self::$_typesMap[$name])) {
+                throw DBALException::unknownColumnType($name);
+            }
+            self::$_typeObjects[$name] = new self::$_typesMap[$name]();
+        }
+
+        return self::$_typeObjects[$name];
+    }
+
+    /**
+     * Adds a custom type to the type map.
+     *
+     * @static
+     * @param string $name Name of the type. This should correspond to what getName() returns.
+     * @param string $className The class name of the custom type.
+     * @throws DBALException
+     */
+    public static function addType($name, $className)
+    {
+        if (isset(self::$_typesMap[$name])) {
+            throw DBALException::typeExists($name);
+        }
+
+        self::$_typesMap[$name] = $className;
+    }
+
+    /**
+     * Checks if exists support for a type.
+     *
+     * @static
+     * @param string $name Name of the type
+     * @return boolean TRUE if type is supported; FALSE otherwise
+     */
+    public static function hasType($name)
+    {
+        return isset(self::$_typesMap[$name]);
+    }
+
+    /**
+     * Overrides an already defined type to use a different implementation.
+     *
+     * @static
+     * @param string $name
+     * @param string $className
+     * @throws DBALException
+     */
+    public static function overrideType($name, $className)
+    {
+        if ( ! isset(self::$_typesMap[$name])) {
+            throw DBALException::typeNotFound($name);
+        }
+        
+        if (isset(self::$_typeObjects[$name])) {
+            unset(self::$_typeObjects[$name]);
+        }
+
+        self::$_typesMap[$name] = $className;
+    }
+
+    /**
+     * Gets the (preferred) binding type for values of this type that
+     * can be used when binding parameters to prepared statements.
+     *
+     * This method should return one of the PDO::PARAM_* constants, that is, one of:
+     *
+     * PDO::PARAM_BOOL
+     * PDO::PARAM_NULL
+     * PDO::PARAM_INT
+     * PDO::PARAM_STR
+     * PDO::PARAM_LOB
+     *
+     * @return integer
+     */
+    public function getBindingType()
+    {
+        return \PDO::PARAM_STR;
+    }
+
+    /**
+     * Get the types array map which holds all registered types and the corresponding
+     * type class
+     *
+     * @return array $typesMap
+     */
+    public static function getTypesMap()
+    {
+        return self::$_typesMap;
+    }
+
+    public function __toString()
+    {
+        $e = explode('\\', get_class($this));
+        return str_replace('Type', '', end($e));
+    }
+
+    /**
+     * Does working with this column require SQL conversion functions?
+     *
+     * This is a metadata function that is required for example in the ORM.
+     * Usage of {@link convertToDatabaseValueSQL} and
+     * {@link convertToPHPValueSQL} works for any type and mostly
+     * does nothing. This method can additionally be used for optimization purposes.
+     *
+     * @return bool
+     */
+    public function canRequireSQLConversion()
+    {
+        return false;
+    }
+
+    /**
+     * Modifies the SQL expression (identifier, parameter) to convert to a database value.
+     *
+     * @param string $sqlExpr
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
+    {
+        return $sqlExpr;
+    }
+
+    /**
+     * Modifies the SQL expression (identifier, parameter) to convert to a PHP value.
+     *
+     * @param string $sqlExpr
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function convertToPHPValueSQL($sqlExpr, $platform)
+    {
+        return $sqlExpr;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/VarDateTimeType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/VarDateTimeType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Types/VarDateTimeType.php	(revision 345)
@@ -0,0 +1,60 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\DBAL\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * Variable DateTime Type using date_create() instead of DateTime::createFromFormat()
+ *
+ * This type has performance implications as it runs twice as long as the regular
+ * {@see DateTimeType}, however in certain PostgreSQL configurations with
+ * TIMESTAMP(n) columns where n > 0 it is necessary to use this type.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class VarDateTimeType extends DateTimeType
+{
+    /**
+     * @throws ConversionException
+     * @param string $value
+     * @param AbstractPlatform $platform
+     * @return DateTime
+     */
+    public function convertToPHPValue($value, AbstractPlatform $platform)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $val = date_create($value);
+        if (!$val) {
+            throw ConversionException::conversionFailed($value, $this->getName());
+        }
+        return $val;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Version.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Version.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Version.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Class to store and retrieve the version of Doctrine
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Version
+{
+    /**
+     * Current Doctrine Version
+     */
+    const VERSION = '2.2.2';
+
+    /**
+     * Compares a Doctrine version with the current one.
+     *
+     * @param string $version Doctrine version to compare.
+     * @return int Returns -1 if older, 0 if it is the same, 1 if version
+     *             passed as argument is newer.
+     */
+    public static function compare($version)
+    {
+        $currentVersion = str_replace(' ', '', strtolower(self::VERSION));
+        $version = str_replace(' ', '', $version);
+
+        return version_compare($version, $currentVersion);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/AbstractQuery.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/AbstractQuery.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/AbstractQuery.php	(revision 345)
@@ -0,0 +1,820 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Cache\QueryCacheProfile,
+    Doctrine\ORM\Query\QueryException,
+    Doctrine\ORM\Internal\Hydration\CacheHydrator;
+
+/**
+ * Base contract for ORM queries. Base class for Query and NativeQuery.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Konsta Vesterinen <kvesteri@cc.hut.fi>
+ */
+abstract class AbstractQuery
+{
+    /* Hydration mode constants */
+    /**
+     * Hydrates an object graph. This is the default behavior.
+     */
+    const HYDRATE_OBJECT = 1;
+    /**
+     * Hydrates an array graph.
+     */
+    const HYDRATE_ARRAY = 2;
+    /**
+     * Hydrates a flat, rectangular result set with scalar values.
+     */
+    const HYDRATE_SCALAR = 3;
+    /**
+     * Hydrates a single scalar value.
+     */
+    const HYDRATE_SINGLE_SCALAR = 4;
+
+    /**
+     * Very simple object hydrator (optimized for performance).
+     */
+    const HYDRATE_SIMPLEOBJECT = 5;
+
+    /**
+     * @var array The parameter map of this query.
+     */
+    protected $_params = array();
+
+    /**
+     * @var array The parameter type map of this query.
+     */
+    protected $_paramTypes = array();
+
+    /**
+     * @var ResultSetMapping The user-specified ResultSetMapping to use.
+     */
+    protected $_resultSetMapping;
+
+    /**
+     * @var \Doctrine\ORM\EntityManager The entity manager used by this query object.
+     */
+    protected $_em;
+
+    /**
+     * @var array The map of query hints.
+     */
+    protected $_hints = array();
+
+    /**
+     * @var integer The hydration mode.
+     */
+    protected $_hydrationMode = self::HYDRATE_OBJECT;
+
+    /**
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile
+     */
+    protected $_queryCacheProfile;
+
+    /**
+     * @var boolean Boolean value that indicates whether or not expire the result cache.
+     */
+    protected $_expireResultCache = false;
+
+    /**
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile
+     */
+    protected $_hydrationCacheProfile;
+
+    /**
+     * Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
+     *
+     * @param \Doctrine\ORM\EntityManager $entityManager
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em = $em;
+    }
+
+    /**
+     * Retrieves the associated EntityManager of this Query instance.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * Frees the resources used by the query object.
+     *
+     * Resets Parameters, Parameter Types and Query Hints.
+     *
+     * @return void
+     */
+    public function free()
+    {
+        $this->_params = array();
+        $this->_paramTypes = array();
+        $this->_hints = array();
+    }
+
+    /**
+     * Get all defined parameters.
+     *
+     * @return array The defined query parameters.
+     */
+    public function getParameters()
+    {
+        return $this->_params;
+    }
+
+    /**
+     * Get all defined parameter types.
+     *
+     * @return array The defined query parameter types.
+     */
+    public function getParameterTypes()
+    {
+        return $this->_paramTypes;
+    }
+
+    /**
+     * Gets a query parameter.
+     *
+     * @param mixed $key The key (index or name) of the bound parameter.
+     * @return mixed The value of the bound parameter.
+     */
+    public function getParameter($key)
+    {
+        if (isset($this->_params[$key])) {
+            return $this->_params[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a query parameter type.
+     *
+     * @param mixed $key The key (index or name) of the bound parameter.
+     * @return mixed The parameter type of the bound parameter.
+     */
+    public function getParameterType($key)
+    {
+        if (isset($this->_paramTypes[$key])) {
+            return $this->_paramTypes[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets the SQL query that corresponds to this query object.
+     * The returned SQL syntax depends on the connection driver that is used
+     * by this query object at the time of this method call.
+     *
+     * @return string SQL query
+     */
+    abstract public function getSQL();
+
+    /**
+     * Sets a query parameter.
+     *
+     * @param string|integer $key The parameter position or name.
+     * @param mixed $value The parameter value.
+     * @param string $type The parameter type. If specified, the given value will be run through
+     *                     the type conversion of this type. This is usually not needed for
+     *                     strings and numeric types.
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function setParameter($key, $value, $type = null)
+    {
+        $key = trim($key, ':');
+
+        $value = $this->processParameterValue($value);
+        if ($type === null) {
+            $type = Query\ParameterTypeInferer::inferType($value);
+        }
+
+        $this->_paramTypes[$key] = $type;
+        $this->_params[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Process an individual parameter value
+     *
+     * @param mixed $value
+     * @return array
+     */
+    private function processParameterValue($value)
+    {
+        switch (true) {
+            case is_array($value):
+                for ($i = 0, $l = count($value); $i < $l; $i++) {
+                    $paramValue = $this->processParameterValue($value[$i]);
+                    $value[$i] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue;
+                }
+
+                return $value;
+
+            case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value)):
+                return $this->convertObjectParameterToScalarValue($value);
+
+            default:
+                return $value;
+        }
+    }
+
+    protected function convertObjectParameterToScalarValue($value)
+    {
+        $class = $this->_em->getClassMetadata(get_class($value));
+
+        if ($class->isIdentifierComposite) {
+            throw new \InvalidArgumentException("Binding an entity with a composite primary key to a query is not supported. You should split the parameter into the explicit fields and bind them seperately.");
+        }
+
+        if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
+            $values = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+        } else {
+            $values = $class->getIdentifierValues($value);
+        }
+
+        $value = $values[$class->getSingleIdentifierFieldName()];
+        if (!$value) {
+            throw new \InvalidArgumentException("Binding entities to query parameters only allowed for entities that have an identifier.");
+        }
+
+        return $value;
+    }
+
+    /**
+     * Sets a collection of query parameters.
+     *
+     * @param array $params
+     * @param array $types
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function setParameters(array $params, array $types = array())
+    {
+        foreach ($params as $key => $value) {
+            $this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets the ResultSetMapping that should be used for hydration.
+     *
+     * @param ResultSetMapping $rsm
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setResultSetMapping(Query\ResultSetMapping $rsm)
+    {
+        $this->_resultSetMapping = $rsm;
+
+        return $this;
+    }
+
+    /**
+     * Set a cache profile for hydration caching.
+     *
+     * If no result cache driver is set in the QueryCacheProfile, the default
+     * result cache driver is used from the configuration.
+     *
+     * Important: Hydration caching does NOT register entities in the
+     * UnitOfWork when retrieved from the cache. Never use result cached
+     * entities for requests that also flush the EntityManager. If you want
+     * some form of caching with UnitOfWork registration you should use
+     * {@see AbstractQuery::setResultCacheProfile()}.
+     *
+     * @example
+     * $lifetime = 100;
+     * $resultKey = "abc";
+     * $query->setHydrationCacheProfile(new QueryCacheProfile());
+     * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
+     *
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
+    {
+        if ( ! $profile->getResultCacheDriver()) {
+            $resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
+            $profile = $profile->setResultCacheDriver($resultCacheDriver);
+        }
+
+        $this->_hydrationCacheProfile = $profile;
+
+        return $this;
+    }
+
+    /**
+     * @return \Doctrine\DBAL\Cache\QueryCacheProfile
+     */
+    public function getHydrationCacheProfile()
+    {
+        return $this->_hydrationCacheProfile;
+    }
+
+    /**
+     * Set a cache profile for the result cache.
+     *
+     * If no result cache driver is set in the QueryCacheProfile, the default
+     * result cache driver is used from the configuration.
+     *
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setResultCacheProfile(QueryCacheProfile $profile = null)
+    {
+        if ( ! $profile->getResultCacheDriver()) {
+            $resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
+            $profile = $profile->setResultCacheDriver($resultCacheDriver);
+        }
+
+        $this->_queryCacheProfile = $profile;
+
+        return $this;
+    }
+
+    /**
+     * Defines a cache driver to be used for caching result sets and implictly enables caching.
+     *
+     * @param \Doctrine\Common\Cache\Cache $driver Cache driver
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setResultCacheDriver($resultCacheDriver = null)
+    {
+        if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
+            throw ORMException::invalidResultCacheDriver();
+        }
+
+        $this->_queryCacheProfile = $this->_queryCacheProfile
+            ? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
+            : new QueryCacheProfile(0, null, $resultCacheDriver);
+
+        return $this;
+    }
+
+    /**
+     * Returns the cache driver used for caching result sets.
+     *
+     * @deprecated
+     * @return \Doctrine\Common\Cache\Cache Cache driver
+     */
+    public function getResultCacheDriver()
+    {
+        if ($this->_queryCacheProfile && $this->_queryCacheProfile->getResultCacheDriver()) {
+            return $this->_queryCacheProfile->getResultCacheDriver();
+        }
+
+        return $this->_em->getConfiguration()->getResultCacheImpl();
+    }
+
+    /**
+     * Set whether or not to cache the results of this query and if so, for
+     * how long and which ID to use for the cache entry.
+     *
+     * @param boolean $bool
+     * @param integer $lifetime
+     * @param string $resultCacheId
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
+    {
+        if ($bool) {
+            $this->setResultCacheLifetime($lifetime);
+            $this->setResultCacheId($resultCacheId);
+
+            return $this;
+        }
+
+        $this->_queryCacheProfile = null;
+
+        return $this;
+    }
+
+    /**
+     * Defines how long the result cache will be active before expire.
+     *
+     * @param integer $lifetime How long the cache entry is valid.
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function setResultCacheLifetime($lifetime)
+    {
+        $lifetime = ($lifetime !== null) ? (int) $lifetime : 0;
+
+        $this->_queryCacheProfile = $this->_queryCacheProfile
+            ? $this->_queryCacheProfile->setLifetime($lifetime)
+            : new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl());
+
+        return $this;
+    }
+
+    /**
+     * Retrieves the lifetime of resultset cache.
+     *
+     * @deprecated
+     * @return integer
+     */
+    public function getResultCacheLifetime()
+    {
+        return $this->_queryCacheProfile ? $this->_queryCacheProfile->getLifetime() : 0;
+    }
+
+    /**
+     * Defines if the result cache is active or not.
+     *
+     * @param boolean $expire Whether or not to force resultset cache expiration.
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function expireResultCache($expire = true)
+    {
+        $this->_expireResultCache = $expire;
+
+        return $this;
+    }
+
+    /**
+     * Retrieves if the resultset cache is active or not.
+     *
+     * @return boolean
+     */
+    public function getExpireResultCache()
+    {
+        return $this->_expireResultCache;
+    }
+
+    /**
+     * @return QueryCacheProfile
+     */
+    public function getQueryCacheProfile()
+    {
+        return $this->_queryCacheProfile;
+    }
+
+    /**
+     * Change the default fetch mode of an association for this query.
+     *
+     * $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
+     *
+     * @param  string $class
+     * @param  string $assocName
+     * @param  int $fetchMode
+     * @return AbstractQuery
+     */
+    public function setFetchMode($class, $assocName, $fetchMode)
+    {
+        if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
+            $fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
+        }
+
+        $this->_hints['fetchMode'][$class][$assocName] = $fetchMode;
+
+        return $this;
+    }
+
+    /**
+     * Defines the processing mode to be used during hydration / result set transformation.
+     *
+     * @param integer $hydrationMode Doctrine processing mode to be used during hydration process.
+     *                               One of the Query::HYDRATE_* constants.
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function setHydrationMode($hydrationMode)
+    {
+        $this->_hydrationMode = $hydrationMode;
+
+        return $this;
+    }
+
+    /**
+     * Gets the hydration mode currently used by the query.
+     *
+     * @return integer
+     */
+    public function getHydrationMode()
+    {
+        return $this->_hydrationMode;
+    }
+
+    /**
+     * Gets the list of results for the query.
+     *
+     * Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
+     *
+     * @return array
+     */
+    public function getResult($hydrationMode = self::HYDRATE_OBJECT)
+    {
+        return $this->execute(array(), $hydrationMode);
+    }
+
+    /**
+     * Gets the array of results for the query.
+     *
+     * Alias for execute(array(), HYDRATE_ARRAY).
+     *
+     * @return array
+     */
+    public function getArrayResult()
+    {
+        return $this->execute(array(), self::HYDRATE_ARRAY);
+    }
+
+    /**
+     * Gets the scalar results for the query.
+     *
+     * Alias for execute(array(), HYDRATE_SCALAR).
+     *
+     * @return array
+     */
+    public function getScalarResult()
+    {
+        return $this->execute(array(), self::HYDRATE_SCALAR);
+    }
+
+    /**
+     * Get exactly one result or null.
+     *
+     * @throws NonUniqueResultException
+     * @param int $hydrationMode
+     * @return mixed
+     */
+    public function getOneOrNullResult($hydrationMode = null)
+    {
+        $result = $this->execute(array(), $hydrationMode);
+
+        if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
+            return null;
+        }
+
+        if ( ! is_array($result)) {
+            return $result;
+        }
+
+        if (count($result) > 1) {
+            throw new NonUniqueResultException;
+        }
+
+        return array_shift($result);
+    }
+
+    /**
+     * Gets the single result of the query.
+     *
+     * Enforces the presence as well as the uniqueness of the result.
+     *
+     * If the result is not unique, a NonUniqueResultException is thrown.
+     * If there is no result, a NoResultException is thrown.
+     *
+     * @param integer $hydrationMode
+     * @return mixed
+     * @throws NonUniqueResultException If the query result is not unique.
+     * @throws NoResultException If the query returned no result.
+     */
+    public function getSingleResult($hydrationMode = null)
+    {
+        $result = $this->execute(array(), $hydrationMode);
+
+        if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
+            throw new NoResultException;
+        }
+
+        if ( ! is_array($result)) {
+            return $result;
+        }
+
+        if (count($result) > 1) {
+            throw new NonUniqueResultException;
+        }
+
+        return array_shift($result);
+    }
+
+    /**
+     * Gets the single scalar result of the query.
+     *
+     * Alias for getSingleResult(HYDRATE_SINGLE_SCALAR).
+     *
+     * @return mixed
+     * @throws QueryException If the query result is not unique.
+     */
+    public function getSingleScalarResult()
+    {
+        return $this->getSingleResult(self::HYDRATE_SINGLE_SCALAR);
+    }
+
+    /**
+     * Sets a query hint. If the hint name is not recognized, it is silently ignored.
+     *
+     * @param string $name The name of the hint.
+     * @param mixed $value The value of the hint.
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setHint($name, $value)
+    {
+        $this->_hints[$name] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Gets the value of a query hint. If the hint name is not recognized, FALSE is returned.
+     *
+     * @param string $name The name of the hint.
+     * @return mixed The value of the hint or FALSE, if the hint name is not recognized.
+     */
+    public function getHint($name)
+    {
+        return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
+    }
+
+    /**
+     * Return the key value map of query hints that are currently set.
+     *
+     * @return array
+     */
+    public function getHints()
+    {
+        return $this->_hints;
+    }
+
+    /**
+     * Executes the query and returns an IterableResult that can be used to incrementally
+     * iterate over the result.
+     *
+     * @param array $params The query parameters.
+     * @param integer $hydrationMode The hydration mode to use.
+     * @return \Doctrine\ORM\Internal\Hydration\IterableResult
+     */
+    public function iterate(array $params = array(), $hydrationMode = null)
+    {
+        if ($hydrationMode !== null) {
+            $this->setHydrationMode($hydrationMode);
+        }
+
+        if ($params) {
+            $this->setParameters($params);
+        }
+
+        $stmt = $this->_doExecute();
+
+        return $this->_em->newHydrator($this->_hydrationMode)->iterate(
+            $stmt, $this->_resultSetMapping, $this->_hints
+        );
+    }
+
+    /**
+     * Executes the query.
+     *
+     * @param array $params Any additional query parameters.
+     * @param integer $hydrationMode Processing mode to be used during the hydration process.
+     * @return mixed
+     */
+    public function execute($params = array(), $hydrationMode = null)
+    {
+        if ($hydrationMode !== null) {
+            $this->setHydrationMode($hydrationMode);
+        }
+
+        if ($params) {
+            $this->setParameters($params);
+        }
+
+        $setCacheEntry = function() {};
+
+        if ($this->_hydrationCacheProfile !== null) {
+            list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
+
+            $queryCacheProfile = $this->getHydrationCacheProfile();
+            $cache             = $queryCacheProfile->getResultCacheDriver();
+            $result            = $cache->fetch($cacheKey);
+
+            if (isset($result[$realCacheKey])) {
+                return $result[$realCacheKey];
+            }
+
+            if ( ! $result) {
+                $result = array();
+            }
+
+            $setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
+                $result[$realCacheKey] = $data;
+                $cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
+            };
+        }
+
+        $stmt = $this->_doExecute();
+
+        if (is_numeric($stmt)) {
+            $setCacheEntry($stmt);
+
+            return $stmt;
+        }
+
+        $data = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
+            $stmt, $this->_resultSetMapping, $this->_hints
+        );
+
+        $setCacheEntry($data);
+
+        return $data;
+    }
+
+    /**
+     * Get the result cache id to use to store the result set cache entry.
+     * Will return the configured id if it exists otherwise a hash will be
+     * automatically generated for you.
+     *
+     * @return array ($key, $hash)
+     */
+    protected function getHydrationCacheId()
+    {
+        $params = $this->getParameters();
+
+        foreach ($params AS $key => $value) {
+            $params[$key] = $this->processParameterValue($value);
+        }
+
+        $sql                    = $this->getSQL();
+        $queryCacheProfile      = $this->getHydrationCacheProfile();
+        $hints                  = $this->getHints();
+        $hints['hydrationMode'] = $this->getHydrationMode();
+        ksort($hints);
+
+        return $queryCacheProfile->generateCacheKeys($sql, $params, $hints);
+    }
+
+    /**
+     * Set the result cache id to use to store the result set cache entry.
+     * If this is not explicitely set by the developer then a hash is automatically
+     * generated for you.
+     *
+     * @param string $id
+     * @return \Doctrine\ORM\AbstractQuery This query instance.
+     */
+    public function setResultCacheId($id)
+    {
+        $this->_queryCacheProfile = $this->_queryCacheProfile
+            ? $this->_queryCacheProfile->setCacheKey($id)
+            : new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl());
+
+        return $this;
+    }
+
+    /**
+     * Get the result cache id to use to store the result set cache entry if set.
+     *
+     * @deprecated
+     * @return string
+     */
+    public function getResultCacheId()
+    {
+        return $this->_queryCacheProfile ? $this->_queryCacheProfile->getCacheKey() : null;
+    }
+
+    /**
+     * Executes the query and returns a the resulting Statement object.
+     *
+     * @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
+     */
+    abstract protected function _doExecute();
+
+    /**
+     * Cleanup Query resource when clone is called.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->_params = array();
+        $this->_paramTypes = array();
+        $this->_hints = array();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Configuration.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Configuration.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Configuration.php	(revision 345)
@@ -0,0 +1,573 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\Common\Cache\Cache,
+    Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationRegistry,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\ORM\Mapping\Driver\Driver,
+    Doctrine\ORM\Mapping\Driver\AnnotationDriver;
+
+/**
+ * Configuration container for all configuration options of Doctrine.
+ * It combines all configuration options from DBAL & ORM.
+ *
+ * @since 2.0
+ * @internal When adding a new configuration option just write a getter/setter pair.
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Configuration extends \Doctrine\DBAL\Configuration
+{
+    /**
+     * Sets the directory where Doctrine generates any necessary proxy class files.
+     *
+     * @param string $dir
+     */
+    public function setProxyDir($dir)
+    {
+        $this->_attributes['proxyDir'] = $dir;
+    }
+
+    /**
+     * Gets the directory where Doctrine generates any necessary proxy class files.
+     *
+     * @return string
+     */
+    public function getProxyDir()
+    {
+        return isset($this->_attributes['proxyDir']) ?
+                $this->_attributes['proxyDir'] : null;
+    }
+
+    /**
+     * Gets a boolean flag that indicates whether proxy classes should always be regenerated
+     * during each script execution.
+     *
+     * @return boolean
+     */
+    public function getAutoGenerateProxyClasses()
+    {
+        return isset($this->_attributes['autoGenerateProxyClasses']) ?
+                $this->_attributes['autoGenerateProxyClasses'] : true;
+    }
+
+    /**
+     * Sets a boolean flag that indicates whether proxy classes should always be regenerated
+     * during each script execution.
+     *
+     * @param boolean $bool
+     */
+    public function setAutoGenerateProxyClasses($bool)
+    {
+        $this->_attributes['autoGenerateProxyClasses'] = $bool;
+    }
+
+    /**
+     * Gets the namespace where proxy classes reside.
+     *
+     * @return string
+     */
+    public function getProxyNamespace()
+    {
+        return isset($this->_attributes['proxyNamespace']) ?
+                $this->_attributes['proxyNamespace'] : null;
+    }
+
+    /**
+     * Sets the namespace where proxy classes reside.
+     *
+     * @param string $ns
+     */
+    public function setProxyNamespace($ns)
+    {
+        $this->_attributes['proxyNamespace'] = $ns;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for metadata caching.
+     *
+     * @param Driver $driverImpl
+     * @todo Force parameter to be a Closure to ensure lazy evaluation
+     *       (as soon as a metadata cache is in effect, the driver never needs to initialize).
+     */
+    public function setMetadataDriverImpl(Driver $driverImpl)
+    {
+        $this->_attributes['metadataDriverImpl'] = $driverImpl;
+    }
+
+    /**
+     * Add a new default annotation driver with a correctly configured annotation reader.
+     *
+     * @param array $paths
+     * @return Mapping\Driver\AnnotationDriver
+     */
+    public function newDefaultAnnotationDriver($paths = array())
+    {
+        if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) {
+            // Register the ORM Annotations in the AnnotationRegistry
+            AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
+
+            $reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
+            $reader->addNamespace('Doctrine\ORM\Mapping');
+            $reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache());
+        } else if (version_compare(\Doctrine\Common\Version::VERSION, '2.1.0-DEV', '>=')) {
+            // Register the ORM Annotations in the AnnotationRegistry
+            AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
+
+            $reader = new AnnotationReader();
+            $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
+            $reader->setIgnoreNotImportedAnnotations(true);
+            $reader->setEnableParsePhpImports(false);
+            $reader = new \Doctrine\Common\Annotations\CachedReader(
+                new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
+            );
+        } else {
+            $reader = new AnnotationReader();
+            $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
+        }
+        return new AnnotationDriver($reader, (array)$paths);
+    }
+
+    /**
+     * Adds a namespace under a certain alias.
+     *
+     * @param string $alias
+     * @param string $namespace
+     */
+    public function addEntityNamespace($alias, $namespace)
+    {
+        $this->_attributes['entityNamespaces'][$alias] = $namespace;
+    }
+
+    /**
+     * Resolves a registered namespace alias to the full namespace.
+     *
+     * @param string $entityNamespaceAlias
+     * @return string
+     * @throws MappingException
+     */
+    public function getEntityNamespace($entityNamespaceAlias)
+    {
+        if ( ! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
+            throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
+        }
+
+        return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
+    }
+
+    /**
+     * Set the entity alias map
+     *
+     * @param array $entityAliasMap
+     * @return void
+     */
+    public function setEntityNamespaces(array $entityNamespaces)
+    {
+        $this->_attributes['entityNamespaces'] = $entityNamespaces;
+    }
+
+    /**
+     * Retrieves the list of registered entity namespace aliases.
+     *
+     * @return array
+     */
+    public function getEntityNamespaces()
+    {
+        return $this->_attributes['entityNamespaces'];
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for the mapping metadata.
+     *
+     * @throws ORMException
+     * @return Mapping\Driver\Driver
+     */
+    public function getMetadataDriverImpl()
+    {
+        return isset($this->_attributes['metadataDriverImpl']) ?
+                $this->_attributes['metadataDriverImpl'] : null;
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for the query cache (SQL cache).
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getQueryCacheImpl()
+    {
+        return isset($this->_attributes['queryCacheImpl']) ?
+                $this->_attributes['queryCacheImpl'] : null;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for the query cache (SQL cache).
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheImpl
+     */
+    public function setQueryCacheImpl(Cache $cacheImpl)
+    {
+        $this->_attributes['queryCacheImpl'] = $cacheImpl;
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for the hydration cache (SQL cache).
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getHydrationCacheImpl()
+    {
+        return isset($this->_attributes['hydrationCacheImpl'])
+            ? $this->_attributes['hydrationCacheImpl']
+            : null;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for the hydration cache (SQL cache).
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheImpl
+     */
+    public function setHydrationCacheImpl(Cache $cacheImpl)
+    {
+        $this->_attributes['hydrationCacheImpl'] = $cacheImpl;
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for metadata caching.
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getMetadataCacheImpl()
+    {
+        return isset($this->_attributes['metadataCacheImpl']) ?
+                $this->_attributes['metadataCacheImpl'] : null;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for metadata caching.
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheImpl
+     */
+    public function setMetadataCacheImpl(Cache $cacheImpl)
+    {
+        $this->_attributes['metadataCacheImpl'] = $cacheImpl;
+    }
+
+    /**
+     * Adds a named DQL query to the configuration.
+     *
+     * @param string $name The name of the query.
+     * @param string $dql The DQL query string.
+     */
+    public function addNamedQuery($name, $dql)
+    {
+        $this->_attributes['namedQueries'][$name] = $dql;
+    }
+
+    /**
+     * Gets a previously registered named DQL query.
+     *
+     * @param string $name The name of the query.
+     * @return string The DQL query.
+     */
+    public function getNamedQuery($name)
+    {
+        if ( ! isset($this->_attributes['namedQueries'][$name])) {
+            throw ORMException::namedQueryNotFound($name);
+        }
+        return $this->_attributes['namedQueries'][$name];
+    }
+
+    /**
+     * Adds a named native query to the configuration.
+     *
+     * @param string $name The name of the query.
+     * @param string $sql The native SQL query string.
+     * @param ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
+     */
+    public function addNamedNativeQuery($name, $sql, Query\ResultSetMapping $rsm)
+    {
+        $this->_attributes['namedNativeQueries'][$name] = array($sql, $rsm);
+    }
+
+    /**
+     * Gets the components of a previously registered named native query.
+     *
+     * @param string $name The name of the query.
+     * @return array A tuple with the first element being the SQL string and the second
+     *          element being the ResultSetMapping.
+     */
+    public function getNamedNativeQuery($name)
+    {
+        if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
+            throw ORMException::namedNativeQueryNotFound($name);
+        }
+        return $this->_attributes['namedNativeQueries'][$name];
+    }
+
+    /**
+     * Ensures that this Configuration instance contains settings that are
+     * suitable for a production environment.
+     *
+     * @throws ORMException If a configuration setting has a value that is not
+     *                      suitable for a production environment.
+     */
+    public function ensureProductionSettings()
+    {
+        if ( !$this->getQueryCacheImpl()) {
+            throw ORMException::queryCacheNotConfigured();
+        }
+        if ( !$this->getMetadataCacheImpl()) {
+            throw ORMException::metadataCacheNotConfigured();
+        }
+        if ($this->getAutoGenerateProxyClasses()) {
+            throw ORMException::proxyClassesAlwaysRegenerating();
+        }
+    }
+
+    /**
+     * Registers a custom DQL function that produces a string value.
+     * Such a function can then be used in any DQL statement in any place where string
+     * functions are allowed.
+     *
+     * DQL function names are case-insensitive.
+     *
+     * @param string $name
+     * @param string $className
+     */
+    public function addCustomStringFunction($name, $className)
+    {
+        $this->_attributes['customStringFunctions'][strtolower($name)] = $className;
+    }
+
+    /**
+     * Gets the implementation class name of a registered custom string DQL function.
+     *
+     * @param string $name
+     * @return string
+     */
+    public function getCustomStringFunction($name)
+    {
+        $name = strtolower($name);
+        return isset($this->_attributes['customStringFunctions'][$name]) ?
+                $this->_attributes['customStringFunctions'][$name] : null;
+    }
+
+    /**
+     * Sets a map of custom DQL string functions.
+     *
+     * Keys must be function names and values the FQCN of the implementing class.
+     * The function names will be case-insensitive in DQL.
+     *
+     * Any previously added string functions are discarded.
+     *
+     * @param array $functions The map of custom DQL string functions.
+     */
+    public function setCustomStringFunctions(array $functions)
+    {
+        $this->_attributes['customStringFunctions'] = array_change_key_case($functions);
+    }
+
+    /**
+     * Registers a custom DQL function that produces a numeric value.
+     * Such a function can then be used in any DQL statement in any place where numeric
+     * functions are allowed.
+     *
+     * DQL function names are case-insensitive.
+     *
+     * @param string $name
+     * @param string $className
+     */
+    public function addCustomNumericFunction($name, $className)
+    {
+        $this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
+    }
+
+    /**
+     * Gets the implementation class name of a registered custom numeric DQL function.
+     *
+     * @param string $name
+     * @return string
+     */
+    public function getCustomNumericFunction($name)
+    {
+        $name = strtolower($name);
+        return isset($this->_attributes['customNumericFunctions'][$name]) ?
+                $this->_attributes['customNumericFunctions'][$name] : null;
+    }
+
+    /**
+     * Sets a map of custom DQL numeric functions.
+     *
+     * Keys must be function names and values the FQCN of the implementing class.
+     * The function names will be case-insensitive in DQL.
+     *
+     * Any previously added numeric functions are discarded.
+     *
+     * @param array $functions The map of custom DQL numeric functions.
+     */
+    public function setCustomNumericFunctions(array $functions)
+    {
+        $this->_attributes['customNumericFunctions'] = array_change_key_case($functions);
+    }
+
+    /**
+     * Registers a custom DQL function that produces a date/time value.
+     * Such a function can then be used in any DQL statement in any place where date/time
+     * functions are allowed.
+     *
+     * DQL function names are case-insensitive.
+     *
+     * @param string $name
+     * @param string $className
+     */
+    public function addCustomDatetimeFunction($name, $className)
+    {
+        $this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
+    }
+
+    /**
+     * Gets the implementation class name of a registered custom date/time DQL function.
+     *
+     * @param string $name
+     * @return string
+     */
+    public function getCustomDatetimeFunction($name)
+    {
+        $name = strtolower($name);
+        return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
+                $this->_attributes['customDatetimeFunctions'][$name] : null;
+    }
+
+    /**
+     * Sets a map of custom DQL date/time functions.
+     *
+     * Keys must be function names and values the FQCN of the implementing class.
+     * The function names will be case-insensitive in DQL.
+     *
+     * Any previously added date/time functions are discarded.
+     *
+     * @param array $functions The map of custom DQL date/time functions.
+     */
+    public function setCustomDatetimeFunctions(array $functions)
+    {
+        $this->_attributes['customDatetimeFunctions'] = array_change_key_case($functions);
+    }
+
+    /**
+     * Get the hydrator class for the given hydration mode name.
+     *
+     * @param string $modeName The hydration mode name.
+     * @return string $hydrator The hydrator class name.
+     */
+    public function getCustomHydrationMode($modeName)
+    {
+        return isset($this->_attributes['customHydrationModes'][$modeName]) ?
+            $this->_attributes['customHydrationModes'][$modeName] : null;
+    }
+
+    /**
+     * Add a custom hydration mode.
+     *
+     * @param string $modeName The hydration mode name.
+     * @param string $hydrator The hydrator class name.
+     */
+    public function addCustomHydrationMode($modeName, $hydrator)
+    {
+        $this->_attributes['customHydrationModes'][$modeName] = $hydrator;
+    }
+
+    /**
+     * Set a class metadata factory.
+     *
+     * @param string $cmf
+     */
+    public function setClassMetadataFactoryName($cmfName)
+    {
+        $this->_attributes['classMetadataFactoryName'] = $cmfName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getClassMetadataFactoryName()
+    {
+        if (!isset($this->_attributes['classMetadataFactoryName'])) {
+            $this->_attributes['classMetadataFactoryName'] = 'Doctrine\ORM\Mapping\ClassMetadataFactory';
+        }
+        return $this->_attributes['classMetadataFactoryName'];
+    }
+
+    /**
+     * Add a filter to the list of possible filters.
+     *
+     * @param string $name The name of the filter.
+     * @param string $className The class name of the filter.
+     */
+    public function addFilter($name, $className)
+    {
+        $this->_attributes['filters'][$name] = $className;
+    }
+
+    /**
+     * Gets the class name for a given filter name.
+     *
+     * @param string $name The name of the filter.
+     *
+     * @return string The class name of the filter, or null of it is not
+     *  defined.
+     */
+    public function getFilterClassName($name)
+    {
+        return isset($this->_attributes['filters'][$name]) ?
+                $this->_attributes['filters'][$name] : null;
+    }
+
+    /**
+     * Set default repository class.
+     *
+     * @since 2.2
+     * @param string $className
+     * @throws ORMException If not is a \Doctrine\ORM\EntityRepository
+     */
+    public function setDefaultRepositoryClassName($className)
+    {
+        if ($className != "Doctrine\ORM\EntityRepository" &&
+           !is_subclass_of($className, 'Doctrine\ORM\EntityRepository')){
+            throw ORMException::invalidEntityRepository($className);
+        }
+        $this->_attributes['defaultRepositoryClassName'] = $className;
+    }
+
+    /**
+     * Get default repository class.
+     *
+     * @since 2.2
+     * @return string
+     */
+    public function getDefaultRepositoryClassName()
+    {
+        return isset($this->_attributes['defaultRepositoryClassName']) ?
+                $this->_attributes['defaultRepositoryClassName'] : 'Doctrine\ORM\EntityRepository';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityManager.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityManager.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityManager.php	(revision 345)
@@ -0,0 +1,834 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Closure, Exception,
+    Doctrine\Common\EventManager,
+    Doctrine\Common\Persistence\ObjectManager,
+    Doctrine\DBAL\Connection,
+    Doctrine\DBAL\LockMode,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Mapping\ClassMetadataFactory,
+    Doctrine\ORM\Query\ResultSetMapping,
+    Doctrine\ORM\Proxy\ProxyFactory,
+    Doctrine\ORM\Query\FilterCollection;
+
+/**
+ * The EntityManager is the central access point to ORM functionality.
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EntityManager implements ObjectManager
+{
+    /**
+     * The used Configuration.
+     *
+     * @var \Doctrine\ORM\Configuration
+     */
+    private $config;
+
+    /**
+     * The database connection used by the EntityManager.
+     *
+     * @var \Doctrine\DBAL\Connection
+     */
+    private $conn;
+
+    /**
+     * The metadata factory, used to retrieve the ORM metadata of entity classes.
+     *
+     * @var \Doctrine\ORM\Mapping\ClassMetadataFactory
+     */
+    private $metadataFactory;
+
+    /**
+     * The EntityRepository instances.
+     *
+     * @var array
+     */
+    private $repositories = array();
+
+    /**
+     * The UnitOfWork used to coordinate object-level transactions.
+     *
+     * @var \Doctrine\ORM\UnitOfWork
+     */
+    private $unitOfWork;
+
+    /**
+     * The event manager that is the central point of the event system.
+     *
+     * @var \Doctrine\Common\EventManager
+     */
+    private $eventManager;
+
+    /**
+     * The maintained (cached) hydrators. One instance per type.
+     *
+     * @var array
+     */
+    private $hydrators = array();
+
+    /**
+     * The proxy factory used to create dynamic proxies.
+     *
+     * @var \Doctrine\ORM\Proxy\ProxyFactory
+     */
+    private $proxyFactory;
+
+    /**
+     * The expression builder instance used to generate query expressions.
+     *
+     * @var \Doctrine\ORM\Query\Expr
+     */
+    private $expressionBuilder;
+
+    /**
+     * Whether the EntityManager is closed or not.
+     *
+     * @var bool
+     */
+    private $closed = false;
+
+    /**
+     * Collection of query filters.
+     *
+     * @var Doctrine\ORM\Query\FilterCollection
+     */
+    private $filterCollection;
+
+    /**
+     * Creates a new EntityManager that operates on the given database connection
+     * and uses the given Configuration and EventManager implementations.
+     *
+     * @param \Doctrine\DBAL\Connection $conn
+     * @param \Doctrine\ORM\Configuration $config
+     * @param \Doctrine\Common\EventManager $eventManager
+     */
+    protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
+    {
+        $this->conn = $conn;
+        $this->config = $config;
+        $this->eventManager = $eventManager;
+
+        $metadataFactoryClassName = $config->getClassMetadataFactoryName();
+        $this->metadataFactory = new $metadataFactoryClassName;
+        $this->metadataFactory->setEntityManager($this);
+        $this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
+
+        $this->unitOfWork = new UnitOfWork($this);
+        $this->proxyFactory = new ProxyFactory(
+            $this,
+            $config->getProxyDir(),
+            $config->getProxyNamespace(),
+            $config->getAutoGenerateProxyClasses()
+        );
+    }
+
+    /**
+     * Gets the database connection object used by the EntityManager.
+     *
+     * @return \Doctrine\DBAL\Connection
+     */
+    public function getConnection()
+    {
+        return $this->conn;
+    }
+
+    /**
+     * Gets the metadata factory used to gather the metadata of classes.
+     *
+     * @return \Doctrine\ORM\Mapping\ClassMetadataFactory
+     */
+    public function getMetadataFactory()
+    {
+        return $this->metadataFactory;
+    }
+
+    /**
+     * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
+     *
+     * Example:
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder();
+     *     $expr = $em->getExpressionBuilder();
+     *     $qb->select('u')->from('User', 'u')
+     *         ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
+     * </code>
+     *
+     * @return \Doctrine\ORM\Query\Expr
+     */
+    public function getExpressionBuilder()
+    {
+        if ($this->expressionBuilder === null) {
+            $this->expressionBuilder = new Query\Expr;
+        }
+
+        return $this->expressionBuilder;
+    }
+
+    /**
+     * Starts a transaction on the underlying database connection.
+     *
+     * @deprecated Use {@link getConnection}.beginTransaction().
+     */
+    public function beginTransaction()
+    {
+        $this->conn->beginTransaction();
+    }
+
+    /**
+     * Executes a function in a transaction.
+     *
+     * The function gets passed this EntityManager instance as an (optional) parameter.
+     *
+     * {@link flush} is invoked prior to transaction commit.
+     *
+     * If an exception occurs during execution of the function or flushing or transaction commit,
+     * the transaction is rolled back, the EntityManager closed and the exception re-thrown.
+     *
+     * @param Closure $func The function to execute transactionally.
+     * @return mixed Returns the non-empty value returned from the closure or true instead
+     */
+    public function transactional(Closure $func)
+    {
+        $this->conn->beginTransaction();
+
+        try {
+            $return = $func($this);
+
+            $this->flush();
+            $this->conn->commit();
+
+            return $return ?: true;
+        } catch (Exception $e) {
+            $this->close();
+            $this->conn->rollback();
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Commits a transaction on the underlying database connection.
+     *
+     * @deprecated Use {@link getConnection}.commit().
+     */
+    public function commit()
+    {
+        $this->conn->commit();
+    }
+
+    /**
+     * Performs a rollback on the underlying database connection.
+     *
+     * @deprecated Use {@link getConnection}.rollback().
+     */
+    public function rollback()
+    {
+        $this->conn->rollback();
+    }
+
+    /**
+     * Returns the ORM metadata descriptor for a class.
+     *
+     * The class name must be the fully-qualified class name without a leading backslash
+     * (as it is returned by get_class($obj)) or an aliased class name.
+     *
+     * Examples:
+     * MyProject\Domain\User
+     * sales:PriceRequest
+     *
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     * @internal Performance-sensitive method.
+     */
+    public function getClassMetadata($className)
+    {
+        return $this->metadataFactory->getMetadataFor($className);
+    }
+
+    /**
+     * Creates a new Query object.
+     *
+     * @param string  The DQL string.
+     * @return \Doctrine\ORM\Query
+     */
+    public function createQuery($dql = "")
+    {
+        $query = new Query($this);
+
+        if ( ! empty($dql)) {
+            $query->setDql($dql);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Creates a Query from a named query.
+     *
+     * @param string $name
+     * @return \Doctrine\ORM\Query
+     */
+    public function createNamedQuery($name)
+    {
+        return $this->createQuery($this->config->getNamedQuery($name));
+    }
+
+    /**
+     * Creates a native SQL query.
+     *
+     * @param string $sql
+     * @param ResultSetMapping $rsm The ResultSetMapping to use.
+     * @return NativeQuery
+     */
+    public function createNativeQuery($sql, ResultSetMapping $rsm)
+    {
+        $query = new NativeQuery($this);
+        $query->setSql($sql);
+        $query->setResultSetMapping($rsm);
+
+        return $query;
+    }
+
+    /**
+     * Creates a NativeQuery from a named native query.
+     *
+     * @param string $name
+     * @return \Doctrine\ORM\NativeQuery
+     */
+    public function createNamedNativeQuery($name)
+    {
+        list($sql, $rsm) = $this->config->getNamedNativeQuery($name);
+
+        return $this->createNativeQuery($sql, $rsm);
+    }
+
+    /**
+     * Create a QueryBuilder instance
+     *
+     * @return QueryBuilder $qb
+     */
+    public function createQueryBuilder()
+    {
+        return new QueryBuilder($this);
+    }
+
+    /**
+     * Flushes all changes to objects that have been queued up to now to the database.
+     * This effectively synchronizes the in-memory state of managed objects with the
+     * database.
+     *
+     * If an entity is explicitly passed to this method only this entity and
+     * the cascade-persist semantics + scheduled inserts/removals are synchronized.
+     *
+     * @param object $entity
+     * @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
+     *         makes use of optimistic locking fails.
+     */
+    public function flush($entity = null)
+    {
+        $this->errorIfClosed();
+
+        $this->unitOfWork->commit($entity);
+    }
+
+    /**
+     * Finds an Entity by its identifier.
+     *
+     * This is just a convenient shortcut for getRepository($entityName)->find($id).
+     *
+     * @param string $entityName
+     * @param mixed $identifier
+     * @param int $lockMode
+     * @param int $lockVersion
+     * @return object
+     */
+    public function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null)
+    {
+        return $this->getRepository($entityName)->find($identifier, $lockMode, $lockVersion);
+    }
+
+    /**
+     * Gets a reference to the entity identified by the given type and identifier
+     * without actually loading it, if the entity is not yet loaded.
+     *
+     * @param string $entityName The name of the entity type.
+     * @param mixed $id The entity identifier.
+     * @return object The entity reference.
+     */
+    public function getReference($entityName, $id)
+    {
+        $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
+        if ( ! is_array($id)) {
+            $id = array($class->identifier[0] => $id);
+        }
+        $sortedId = array();
+        foreach ($class->identifier as $identifier) {
+            if (!isset($id[$identifier])) {
+                throw ORMException::missingIdentifierField($class->name, $identifier);
+            }
+            $sortedId[$identifier] = $id[$identifier];
+        }
+
+        // Check identity map first, if its already in there just return it.
+        if ($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) {
+            return ($entity instanceof $class->name) ? $entity : null;
+        }
+
+        if ($class->subClasses) {
+            return $this->find($entityName, $sortedId);
+        }
+
+        if ( ! is_array($sortedId)) {
+            $sortedId = array($class->identifier[0] => $sortedId);
+        }
+
+        $entity = $this->proxyFactory->getProxy($class->name, $sortedId);
+        $this->unitOfWork->registerManaged($entity, $sortedId, array());
+
+        return $entity;
+    }
+
+    /**
+     * Gets a partial reference to the entity identified by the given type and identifier
+     * without actually loading it, if the entity is not yet loaded.
+     *
+     * The returned reference may be a partial object if the entity is not yet loaded/managed.
+     * If it is a partial object it will not initialize the rest of the entity state on access.
+     * Thus you can only ever safely access the identifier of an entity obtained through
+     * this method.
+     *
+     * The use-cases for partial references involve maintaining bidirectional associations
+     * without loading one side of the association or to update an entity without loading it.
+     * Note, however, that in the latter case the original (persistent) entity data will
+     * never be visible to the application (especially not event listeners) as it will
+     * never be loaded in the first place.
+     *
+     * @param string $entityName The name of the entity type.
+     * @param mixed $identifier The entity identifier.
+     * @return object The (partial) entity reference.
+     */
+    public function getPartialReference($entityName, $identifier)
+    {
+        $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
+
+        // Check identity map first, if its already in there just return it.
+        if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
+            return ($entity instanceof $class->name) ? $entity : null;
+        }
+
+        if ( ! is_array($identifier)) {
+            $identifier = array($class->identifier[0] => $identifier);
+        }
+
+        $entity = $class->newInstance();
+        $class->setIdentifierValues($entity, $identifier);
+        $this->unitOfWork->registerManaged($entity, $identifier, array());
+        $this->unitOfWork->markReadOnly($entity);
+
+        return $entity;
+    }
+
+    /**
+     * Clears the EntityManager. All entities that are currently managed
+     * by this EntityManager become detached.
+     *
+     * @param string $entityName if given, only entities of this type will get detached
+     */
+    public function clear($entityName = null)
+    {
+        $this->unitOfWork->clear($entityName);
+    }
+
+    /**
+     * Closes the EntityManager. All entities that are currently managed
+     * by this EntityManager become detached. The EntityManager may no longer
+     * be used after it is closed.
+     */
+    public function close()
+    {
+        $this->clear();
+        $this->closed = true;
+    }
+
+    /**
+     * Tells the EntityManager to make an instance managed and persistent.
+     *
+     * The entity will be entered into the database at or before transaction
+     * commit or as a result of the flush operation.
+     *
+     * NOTE: The persist operation always considers entities that are not yet known to
+     * this EntityManager as NEW. Do not pass detached entities to the persist operation.
+     *
+     * @param object $object The instance to make managed and persistent.
+     */
+    public function persist($entity)
+    {
+        if ( ! is_object($entity)) {
+            throw new \InvalidArgumentException(gettype($entity));
+        }
+
+        $this->errorIfClosed();
+
+        $this->unitOfWork->persist($entity);
+    }
+
+    /**
+     * Removes an entity instance.
+     *
+     * A removed entity will be removed from the database at or before transaction commit
+     * or as a result of the flush operation.
+     *
+     * @param object $entity The entity instance to remove.
+     */
+    public function remove($entity)
+    {
+        if ( ! is_object($entity)) {
+            throw new \InvalidArgumentException(gettype($entity));
+        }
+
+        $this->errorIfClosed();
+
+        $this->unitOfWork->remove($entity);
+    }
+
+    /**
+     * Refreshes the persistent state of an entity from the database,
+     * overriding any local changes that have not yet been persisted.
+     *
+     * @param object $entity The entity to refresh.
+     */
+    public function refresh($entity)
+    {
+        if ( ! is_object($entity)) {
+            throw new \InvalidArgumentException(gettype($entity));
+        }
+
+        $this->errorIfClosed();
+
+        $this->unitOfWork->refresh($entity);
+    }
+
+    /**
+     * Detaches an entity from the EntityManager, causing a managed entity to
+     * become detached.  Unflushed changes made to the entity if any
+     * (including removal of the entity), will not be synchronized to the database.
+     * Entities which previously referenced the detached entity will continue to
+     * reference it.
+     *
+     * @param object $entity The entity to detach.
+     */
+    public function detach($entity)
+    {
+        if ( ! is_object($entity)) {
+            throw new \InvalidArgumentException(gettype($entity));
+        }
+
+        $this->unitOfWork->detach($entity);
+    }
+
+    /**
+     * Merges the state of a detached entity into the persistence context
+     * of this EntityManager and returns the managed copy of the entity.
+     * The entity passed to merge will not become associated/managed with this EntityManager.
+     *
+     * @param object $entity The detached entity to merge into the persistence context.
+     * @return object The managed copy of the entity.
+     */
+    public function merge($entity)
+    {
+        if ( ! is_object($entity)) {
+            throw new \InvalidArgumentException(gettype($entity));
+        }
+
+        $this->errorIfClosed();
+
+        return $this->unitOfWork->merge($entity);
+    }
+
+    /**
+     * Creates a copy of the given entity. Can create a shallow or a deep copy.
+     *
+     * @param object $entity  The entity to copy.
+     * @return object  The new entity.
+     * @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e:
+     * Fatal error: Maximum function nesting level of '100' reached, aborting!
+     */
+    public function copy($entity, $deep = false)
+    {
+        throw new \BadMethodCallException("Not implemented.");
+    }
+
+    /**
+     * Acquire a lock on the given entity.
+     *
+     * @param object $entity
+     * @param int $lockMode
+     * @param int $lockVersion
+     * @throws OptimisticLockException
+     * @throws PessimisticLockException
+     */
+    public function lock($entity, $lockMode, $lockVersion = null)
+    {
+        $this->unitOfWork->lock($entity, $lockMode, $lockVersion);
+    }
+
+    /**
+     * Gets the repository for an entity class.
+     *
+     * @param string $entityName The name of the entity.
+     * @return EntityRepository The repository class.
+     */
+    public function getRepository($entityName)
+    {
+        $entityName = ltrim($entityName, '\\');
+
+        if (isset($this->repositories[$entityName])) {
+            return $this->repositories[$entityName];
+        }
+
+        $metadata = $this->getClassMetadata($entityName);
+        $repositoryClassName = $metadata->customRepositoryClassName;
+
+        if ($repositoryClassName === null) {
+            $repositoryClassName = $this->config->getDefaultRepositoryClassName();
+        }
+
+        $repository = new $repositoryClassName($this, $metadata);
+
+        $this->repositories[$entityName] = $repository;
+
+        return $repository;
+    }
+
+    /**
+     * Determines whether an entity instance is managed in this EntityManager.
+     *
+     * @param object $entity
+     * @return boolean TRUE if this EntityManager currently manages the given entity, FALSE otherwise.
+     */
+    public function contains($entity)
+    {
+        return $this->unitOfWork->isScheduledForInsert($entity)
+            || $this->unitOfWork->isInIdentityMap($entity)
+            && ! $this->unitOfWork->isScheduledForDelete($entity);
+    }
+
+    /**
+     * Gets the EventManager used by the EntityManager.
+     *
+     * @return \Doctrine\Common\EventManager
+     */
+    public function getEventManager()
+    {
+        return $this->eventManager;
+    }
+
+    /**
+     * Gets the Configuration used by the EntityManager.
+     *
+     * @return \Doctrine\ORM\Configuration
+     */
+    public function getConfiguration()
+    {
+        return $this->config;
+    }
+
+    /**
+     * Throws an exception if the EntityManager is closed or currently not active.
+     *
+     * @throws ORMException If the EntityManager is closed.
+     */
+    private function errorIfClosed()
+    {
+        if ($this->closed) {
+            throw ORMException::entityManagerClosed();
+        }
+    }
+
+    /**
+     * Check if the Entity manager is open or closed.
+     *
+     * @return bool
+     */
+    public function isOpen()
+    {
+        return (!$this->closed);
+    }
+
+    /**
+     * Gets the UnitOfWork used by the EntityManager to coordinate operations.
+     *
+     * @return \Doctrine\ORM\UnitOfWork
+     */
+    public function getUnitOfWork()
+    {
+        return $this->unitOfWork;
+    }
+
+    /**
+     * Gets a hydrator for the given hydration mode.
+     *
+     * This method caches the hydrator instances which is used for all queries that don't
+     * selectively iterate over the result.
+     *
+     * @param int $hydrationMode
+     * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
+     */
+    public function getHydrator($hydrationMode)
+    {
+        if ( ! isset($this->hydrators[$hydrationMode])) {
+            $this->hydrators[$hydrationMode] = $this->newHydrator($hydrationMode);
+        }
+
+        return $this->hydrators[$hydrationMode];
+    }
+
+    /**
+     * Create a new instance for the given hydration mode.
+     *
+     * @param  int $hydrationMode
+     * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
+     */
+    public function newHydrator($hydrationMode)
+    {
+        switch ($hydrationMode) {
+            case Query::HYDRATE_OBJECT:
+                return new Internal\Hydration\ObjectHydrator($this);
+
+            case Query::HYDRATE_ARRAY:
+                return new Internal\Hydration\ArrayHydrator($this);
+
+            case Query::HYDRATE_SCALAR:
+                return new Internal\Hydration\ScalarHydrator($this);
+
+            case Query::HYDRATE_SINGLE_SCALAR:
+                return new Internal\Hydration\SingleScalarHydrator($this);
+
+            case Query::HYDRATE_SIMPLEOBJECT:
+                return new Internal\Hydration\SimpleObjectHydrator($this);
+
+            default:
+                if ($class = $this->config->getCustomHydrationMode($hydrationMode)) {
+                    return new $class($this);
+                }
+        }
+
+        throw ORMException::invalidHydrationMode($hydrationMode);
+    }
+
+    /**
+     * Gets the proxy factory used by the EntityManager to create entity proxies.
+     *
+     * @return ProxyFactory
+     */
+    public function getProxyFactory()
+    {
+        return $this->proxyFactory;
+    }
+
+    /**
+     * Helper method to initialize a lazy loading proxy or persistent collection.
+     *
+     * This method is a no-op for other objects
+     *
+     * @param object $obj
+     */
+    public function initializeObject($obj)
+    {
+        $this->unitOfWork->initializeObject($obj);
+    }
+
+    /**
+     * Factory method to create EntityManager instances.
+     *
+     * @param mixed $conn An array with the connection parameters or an existing
+     *      Connection instance.
+     * @param Configuration $config The Configuration instance to use.
+     * @param EventManager $eventManager The EventManager instance to use.
+     * @return EntityManager The created EntityManager.
+     */
+    public static function create($conn, Configuration $config, EventManager $eventManager = null)
+    {
+        if ( ! $config->getMetadataDriverImpl()) {
+            throw ORMException::missingMappingDriverImpl();
+        }
+
+        switch (true) {
+            case (is_array($conn)):
+                $conn = \Doctrine\DBAL\DriverManager::getConnection(
+                    $conn, $config, ($eventManager ?: new EventManager())
+                );
+                break;
+
+            case ($conn instanceof Connection):
+                if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
+                     throw ORMException::mismatchedEventManager();
+                }
+                break;
+
+            default:
+                throw new \InvalidArgumentException("Invalid argument: " . $conn);
+        }
+
+        return new EntityManager($conn, $config, $conn->getEventManager());
+    }
+
+    /**
+     * Gets the enabled filters.
+     *
+     * @return FilterCollection The active filter collection.
+     */
+    public function getFilters()
+    {
+        if (null === $this->filterCollection) {
+            $this->filterCollection = new FilterCollection($this);
+        }
+
+        return $this->filterCollection;
+    }
+
+    /**
+     * Checks whether the state of the filter collection is clean.
+     *
+     * @return boolean True, if the filter collection is clean.
+     */
+    public function isFiltersStateClean()
+    {
+        return null === $this->filterCollection
+           || $this->filterCollection->isClean();
+    }
+
+    /**
+     * Checks whether the Entity Manager has filters.
+     *
+     * @return True, if the EM has a filter collection.
+     */
+    public function hasFilters()
+    {
+        return null !== $this->filterCollection;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityNotFoundException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityNotFoundException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityNotFoundException.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Exception thrown when a Proxy fails to retrieve an Entity result.
+ *
+ * @author robo
+ * @since 2.0
+ */
+class EntityNotFoundException extends ORMException
+{
+    public function __construct()
+    {
+        parent::__construct('Entity was not found.');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityRepository.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityRepository.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/EntityRepository.php	(revision 345)
@@ -0,0 +1,272 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\DBAL\LockMode;
+use Doctrine\Common\Persistence\ObjectRepository;
+
+/**
+ * An EntityRepository serves as a repository for entities with generic as well as
+ * business specific methods for retrieving entities.
+ *
+ * This class is designed for inheritance and users can subclass this class to
+ * write their own repositories with business-specific methods to locate entities.
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EntityRepository implements ObjectRepository
+{
+    /**
+     * @var string
+     */
+    protected $_entityName;
+
+    /**
+     * @var EntityManager
+     */
+    protected $_em;
+
+    /**
+     * @var \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    protected $_class;
+
+    /**
+     * Initializes a new <tt>EntityRepository</tt>.
+     *
+     * @param EntityManager $em The EntityManager to use.
+     * @param ClassMetadata $classMetadata The class descriptor.
+     */
+    public function __construct($em, Mapping\ClassMetadata $class)
+    {
+        $this->_entityName = $class->name;
+        $this->_em = $em;
+        $this->_class = $class;
+    }
+
+    /**
+     * Create a new QueryBuilder instance that is prepopulated for this entity name
+     *
+     * @param string $alias
+     * @return QueryBuilder $qb
+     */
+    public function createQueryBuilder($alias)
+    {
+        return $this->_em->createQueryBuilder()
+            ->select($alias)
+            ->from($this->_entityName, $alias);
+    }
+
+    /**
+     * Create a new Query instance based on a predefined metadata named query.
+     *
+     * @param string $queryName
+     * @return Query
+     */
+    public function createNamedQuery($queryName)
+    {
+        return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
+    }
+
+    /**
+     * Clears the repository, causing all managed entities to become detached.
+     */
+    public function clear()
+    {
+        $this->_em->clear($this->_class->rootEntityName);
+    }
+
+    /**
+     * Finds an entity by its primary key / identifier.
+     *
+     * @param $id The identifier.
+     * @param int $lockMode
+     * @param int $lockVersion
+     * @return object The entity.
+     */
+    public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
+    {
+        if ( ! is_array($id)) {
+            $id = array($this->_class->identifier[0] => $id);
+        }
+        $sortedId = array();
+        foreach ($this->_class->identifier as $identifier) {
+            if (!isset($id[$identifier])) {
+                throw ORMException::missingIdentifierField($this->_class->name, $identifier);
+            }
+            $sortedId[$identifier] = $id[$identifier];
+        }
+
+        // Check identity map first
+        if ($entity = $this->_em->getUnitOfWork()->tryGetById($sortedId, $this->_class->rootEntityName)) {
+            if ( ! ($entity instanceof $this->_class->name)) {
+                return null;
+            }
+
+            switch ($lockMode) {
+                case LockMode::OPTIMISTIC:
+                    $this->_em->lock($entity, $lockMode, $lockVersion);
+                    break;
+                case LockMode::PESSIMISTIC_READ:
+                case LockMode::PESSIMISTIC_WRITE:
+                    $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
+                    $persister->refresh($sortedId, $entity, $lockMode);
+                    break;
+            }
+
+            return $entity; // Hit!
+        }
+
+        switch ($lockMode) {
+            case LockMode::NONE:
+                return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
+
+            case LockMode::OPTIMISTIC:
+                if ( ! $this->_class->isVersioned) {
+                    throw OptimisticLockException::notVersioned($this->_entityName);
+                }
+
+                $entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
+
+                $this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
+
+                return $entity;
+
+            default:
+                if ( ! $this->_em->getConnection()->isTransactionActive()) {
+                    throw TransactionRequiredException::transactionRequired();
+                }
+
+                return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId, null, null, array(), $lockMode);
+        }
+    }
+
+    /**
+     * Finds all entities in the repository.
+     *
+     * @return array The entities.
+     */
+    public function findAll()
+    {
+        return $this->findBy(array());
+    }
+
+    /**
+     * Finds entities by a set of criteria.
+     *
+     * @param array $criteria
+     * @param array|null $orderBy
+     * @param int|null $limit
+     * @param int|null $offset
+     * @return array The objects.
+     */
+    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+    {
+        return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset);
+    }
+
+    /**
+     * Finds a single entity by a set of criteria.
+     *
+     * @param array $criteria
+     * @return object
+     */
+    public function findOneBy(array $criteria)
+    {
+        return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria, null, null, array(), 0, 1);
+    }
+
+    /**
+     * Adds support for magic finders.
+     *
+     * @return array|object The found entity/entities.
+     * @throws BadMethodCallException  If the method called is an invalid find* method
+     *                                 or no find* method at all and therefore an invalid
+     *                                 method call.
+     */
+    public function __call($method, $arguments)
+    {
+        switch (true) {
+            case (substr($method, 0, 6) == 'findBy'):
+                $by = substr($method, 6, strlen($method));
+                $method = 'findBy';
+                break;
+
+            case (substr($method, 0, 9) == 'findOneBy'):
+                $by = substr($method, 9, strlen($method));
+                $method = 'findOneBy';
+                break;
+
+            default:
+                throw new \BadMethodCallException(
+                    "Undefined method '$method'. The method name must start with ".
+                    "either findBy or findOneBy!"
+                );
+        }
+
+        if (empty($arguments)) {
+            throw ORMException::findByRequiresParameter($method . $by);
+        }
+
+        $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
+
+        if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
+            return $this->$method(array($fieldName => $arguments[0]));
+        }
+
+        throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
+    }
+
+    /**
+     * @return string
+     */
+    protected function getEntityName()
+    {
+        return $this->_entityName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getClassName()
+    {
+        return $this->getEntityName();
+    }
+
+    /**
+     * @return EntityManager
+     */
+    protected function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * @return Mapping\ClassMetadata
+     */
+    protected function getClassMetadata()
+    {
+        return $this->_class;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LifecycleEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LifecycleEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LifecycleEventArgs.php	(revision 345)
@@ -0,0 +1,77 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
+ * of entities.
+ *
+ * @link   www.doctrine-project.org
+ * @since  2.0
+ * @author Roman Borschel <roman@code-factory.de>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LifecycleEventArgs extends EventArgs
+{
+    /**
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * @var object
+     */
+    private $entity;
+
+    /**
+     * Constructor
+     *
+     * @param object $entity
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct($entity, EntityManager $em)
+    {
+        $this->entity = $entity;
+        $this->em     = $em;
+    }
+
+    /**
+     * Retireve associated Entity.
+     *
+     * @return object
+     */
+    public function getEntity()
+    {
+        return $this->entity;
+    }
+
+    /**
+     * Retrieve associated EntityManager.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->em;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Class that holds event arguments for a loadMetadata event.
+ *
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @since  2.0
+ */
+class LoadClassMetadataEventArgs extends EventArgs
+{
+    /**
+     * @var \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    private $classMetadata;
+
+    /**
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * Constructor.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(ClassMetadataInfo $classMetadata, EntityManager $em)
+    {
+        $this->classMetadata = $classMetadata;
+        $this->em            = $em;
+    }
+
+    /**
+     * Retrieve associated ClassMetadata.
+     *
+     * @return \Doctrine\ORM\Mapping\ClassMetadataInfo
+     */
+    public function getClassMetadata()
+    {
+        return $this->classMetadata;
+    }
+
+    /**
+     * Retrieve associated EntityManager.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->em;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnClearEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnClearEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnClearEventArgs.php	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Event;
+
+/**
+ * Provides event arguments for the onClear event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OnClearEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * @var string
+     */
+    private $entityClass;
+
+    /**
+     * Constructor.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     * @param string $entityClass Optional entity class
+     */
+    public function __construct($em, $entityClass = null)
+    {
+        $this->em          = $em;
+        $this->entityClass = $entityClass;
+    }
+
+    /**
+     * Retrieve associated EntityManager.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->em;
+    }
+
+    /**
+     * Name of the entity class that is cleared, or empty if all are cleared.
+     *
+     * @return string
+     */
+    public function getEntityClass()
+    {
+        return $this->entityClass;
+    }
+
+    /**
+     * Check if event clears all entities.
+     *
+     * @return bool
+     */
+    public function clearsAllEntities()
+    {
+        return ($this->entityClass === null);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnFlushEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnFlushEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/OnFlushEventArgs.php	(revision 345)
@@ -0,0 +1,86 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Event;
+
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Provides event arguments for the preFlush event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OnFlushEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var Doctirne\ORM\EntityManager
+     */
+    private $em;
+
+    //private $entitiesToPersist = array();
+    //private $entitiesToRemove = array();
+
+    /**
+     * Constructor.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Retrieve associated EntityManager.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->em;
+    }
+
+    /*
+    public function addEntityToPersist($entity)
+    {
+
+    }
+
+    public function addEntityToRemove($entity)
+    {
+
+    }
+
+    public function addEntityToUpdate($entity)
+    {
+
+    }
+
+    public function getEntitiesToPersist()
+    {
+        return $this->_entitiesToPersist;
+    }
+    */
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PostFlushEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PostFlushEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PostFlushEventArgs.php	(revision 345)
@@ -0,0 +1,61 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Event;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\Common\EventArgs;
+
+/**
+ * Provides event arguments for the postFlush event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @author      Daniel Freudenberger <df@rebuy.de>
+ */
+class PostFlushEventArgs extends EventArgs
+{
+    /**
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * Constructor.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Retrieve associated EntityManager.
+     *
+     * @return \Doctrine\ORM\EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->em;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreFlushEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreFlushEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreFlushEventArgs.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Event;
+
+/**
+ * Provides event arguments for the preFlush event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @version     $Revision$
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class PreFlushEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var EntityManager
+     */
+    private $_em;
+
+    public function __construct($em)
+    {
+        $this->_em = $em;
+    }
+
+    /**
+     * @return EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreUpdateEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreUpdateEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Event/PreUpdateEventArgs.php	(revision 345)
@@ -0,0 +1,131 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Event;
+
+use Doctrine\Common\EventArgs,
+    Doctrine\ORM\EntityManager;
+
+/**
+ * Class that holds event arguments for a preInsert/preUpdate event.
+ *
+ * @author Guilherme Blanco <guilehrmeblanco@hotmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since  2.0
+ */
+class PreUpdateEventArgs extends LifecycleEventArgs
+{
+    /**
+     * @var array
+     */
+    private $entityChangeSet;
+
+    /**
+     * Constructor.
+     *
+     * @param object $entity
+     * @param \Doctrine\ORM\EntityManager $em
+     * @param array $changeSet
+     */
+    public function __construct($entity, EntityManager $em, array &$changeSet)
+    {
+        parent::__construct($entity, $em);
+
+        $this->entityChangeSet = &$changeSet;
+    }
+
+    /**
+     * Retrieve entity changeset.
+     *
+     * @return array
+     */
+    public function getEntityChangeSet()
+    {
+        return $this->entityChangeSet;
+    }
+
+    /**
+     * Check if field has a changeset.
+     *
+     * @return boolean
+     */
+    public function hasChangedField($field)
+    {
+        return isset($this->entityChangeSet[$field]);
+    }
+
+    /**
+     * Get the old value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getOldValue($field)
+    {
+    	$this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][0];
+    }
+
+    /**
+     * Get the new value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getNewValue($field)
+    {
+        $this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][1];
+    }
+
+    /**
+     * Set the new value of this field.
+     *
+     * @param string $field
+     * @param mixed $value
+     */
+    public function setNewValue($field, $value)
+    {
+        $this->assertValidField($field);
+
+        $this->entityChangeSet[$field][1] = $value;
+    }
+
+    /**
+     * Assert the field exists in changeset.
+     *
+     * @param string $field
+     */
+    private function assertValidField($field)
+    {
+    	if ( ! isset($this->entityChangeSet[$field])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
+                $field,
+                get_class($this->getEntity())
+            ));
+        }
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Events.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Events.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Events.php	(revision 345)
@@ -0,0 +1,148 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Container for all ORM events.
+ *
+ * This class cannot be instantiated.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+final class Events
+{
+    private function __construct() {}
+    /**
+     * The preRemove event occurs for a given entity before the respective
+     * EntityManager remove operation for that entity is executed.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const preRemove = 'preRemove';
+    /**
+     * The postRemove event occurs for an entity after the entity has
+     * been deleted. It will be invoked after the database delete operations.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const postRemove = 'postRemove';
+    /**
+     * The prePersist event occurs for a given entity before the respective
+     * EntityManager persist operation for that entity is executed.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const prePersist = 'prePersist';
+    /**
+     * The postPersist event occurs for an entity after the entity has
+     * been made persistent. It will be invoked after the database insert operations.
+     * Generated primary key values are available in the postPersist event.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const postPersist = 'postPersist';
+    /**
+     * The preUpdate event occurs before the database update operations to
+     * entity data.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const preUpdate = 'preUpdate';
+    /**
+     * The postUpdate event occurs after the database update operations to
+     * entity data.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const postUpdate = 'postUpdate';
+    /**
+     * The postLoad event occurs for an entity after the entity has been loaded
+     * into the current EntityManager from the database or after the refresh operation
+     * has been applied to it.
+     *
+     * Note that the postLoad event occurs for an entity before any associations have been
+     * initialized. Therefore it is not safe to access associations in a postLoad callback
+     * or event handler.
+     *
+     * This is an entity lifecycle event.
+     *
+     * @var string
+     */
+    const postLoad = 'postLoad';
+    /**
+     * The loadClassMetadata event occurs after the mapping metadata for a class
+     * has been loaded from a mapping source (annotations/xml/yaml).
+     *
+     * @var string
+     */
+    const loadClassMetadata = 'loadClassMetadata';
+
+    /**
+     * The preFlush event occurs when the EntityManager#flush() operation is invoked,
+     * but before any changes to managed entites have been calculated. This event is
+     * always raised right after EntityManager#flush() call.
+     */
+    const preFlush = 'preFlush';
+
+    /**
+     * The onFlush event occurs when the EntityManager#flush() operation is invoked,
+     * after any changes to managed entities have been determined but before any
+     * actual database operations are executed. The event is only raised if there is
+     * actually something to do for the underlying UnitOfWork. If nothing needs to be done,
+     * the onFlush event is not raised.
+     *
+     * @var string
+     */
+    const onFlush = 'onFlush';
+
+    /**
+     * The postFlush event occurs when the EntityManager#flush() operation is invoked and
+     * after all actual database operations are executed successfully. The event is only raised if there is
+     * actually something to do for the underlying UnitOfWork. If nothing needs to be done,
+     * the postFlush event is not raised. The event won't be raised if an error occurs during the
+     * flush operation.
+     *
+     * @var string
+     */
+    const postFlush = 'postFlush';
+
+    /**
+     * The onClear event occurs when the EntityManager#clear() operation is invoked,
+     * after all references to entities have been removed from the unit of work.
+     *
+     * @var string
+     */
+    const onClear = 'onClear';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AbstractIdGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AbstractIdGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AbstractIdGenerator.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Id;
+
+use Doctrine\ORM\EntityManager;
+
+abstract class AbstractIdGenerator
+{
+    /**
+     * Generates an identifier for an entity.
+     *
+     * @param \Doctrine\ORM\Entity $entity
+     * @return mixed
+     */
+    abstract public function generate(EntityManager $em, $entity);
+
+    /**
+     * Gets whether this generator is a post-insert generator which means that
+     * {@link generate()} must be called after the entity has been inserted
+     * into the database.
+     *
+     * By default, this method returns FALSE. Generators that have this requirement
+     * must override this method and return TRUE.
+     *
+     * @return boolean
+     */
+    public function isPostInsertGenerator()
+    {
+        return false;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AssignedGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AssignedGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/AssignedGenerator.php	(revision 345)
@@ -0,0 +1,71 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Id;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\ORMException;
+
+/**
+ * Special generator for application-assigned identifiers (doesnt really generate anything).
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class AssignedGenerator extends AbstractIdGenerator
+{
+    /**
+     * Returns the identifier assigned to the given entity.
+     *
+     * @param object $entity
+     * @return mixed
+     * @override
+     */
+    public function generate(EntityManager $em, $entity)
+    {
+        $class      = $em->getClassMetadata(get_class($entity));
+        $idFields   = $class->getIdentifierFieldNames();
+        $identifier = array();
+
+        foreach ($idFields as $idField) {
+            $value = $class->reflFields[$idField]->getValue($entity);
+
+            if ( ! isset($value)) {
+                throw ORMException::entityMissingAssignedIdForField($entity, $idField);
+            }
+
+            if (isset($class->associationMappings[$idField])) {
+                if ( ! $em->getUnitOfWork()->isInIdentityMap($value)) {
+                    throw ORMException::entityMissingForeignAssignedId($entity, $value);
+                }
+
+                // NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
+                $value = current($em->getUnitOfWork()->getEntityIdentifier($value));
+            }
+
+            $identifier[$idField] = $value;
+        }
+
+        return $identifier;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/IdentityGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/IdentityGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/IdentityGenerator.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Id;
+
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Id generator that obtains IDs from special "identity" columns. These are columns
+ * that automatically get a database-generated, auto-incremented identifier on INSERT.
+ * This generator obtains the last insert id after such an insert.
+ */
+class IdentityGenerator extends AbstractIdGenerator
+{
+    /** @var string The name of the sequence to pass to lastInsertId(), if any. */
+    private $_seqName;
+
+    /**
+     * @param string $seqName The name of the sequence to pass to lastInsertId()
+     *                        to obtain the last generated identifier within the current
+     *                        database session/connection, if any.
+     */
+    public function __construct($seqName = null)
+    {
+        $this->_seqName = $seqName;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generate(EntityManager $em, $entity)
+    {
+        return (int)$em->getConnection()->lastInsertId($this->_seqName);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPostInsertGenerator()
+    {
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/SequenceGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/SequenceGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/SequenceGenerator.php	(revision 345)
@@ -0,0 +1,106 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Id;
+
+use Serializable, Doctrine\ORM\EntityManager;
+
+/**
+ * Represents an ID generator that uses a database sequence.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class SequenceGenerator extends AbstractIdGenerator implements Serializable
+{
+    private $_allocationSize;
+    private $_sequenceName;
+    private $_nextValue = 0;
+    private $_maxValue = null;
+
+    /**
+     * Initializes a new sequence generator.
+     *
+     * @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
+     * @param string $sequenceName The name of the sequence.
+     * @param integer $allocationSize The allocation size of the sequence.
+     */
+    public function __construct($sequenceName, $allocationSize)
+    {
+        $this->_sequenceName = $sequenceName;
+        $this->_allocationSize = $allocationSize;
+    }
+
+    /**
+     * Generates an ID for the given entity.
+     *
+     * @param object $entity
+     * @return integer|float The generated value.
+     * @override
+     */
+    public function generate(EntityManager $em, $entity)
+    {
+        if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
+            // Allocate new values
+            $conn = $em->getConnection();
+            $sql  = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
+
+            $this->_nextValue = (int)$conn->fetchColumn($sql);
+            $this->_maxValue  = $this->_nextValue + $this->_allocationSize;
+        }
+
+        return $this->_nextValue++;
+    }
+
+    /**
+     * Gets the maximum value of the currently allocated bag of values.
+     *
+     * @return integer|float
+     */
+    public function getCurrentMaxValue()
+    {
+        return $this->_maxValue;
+    }
+
+    /**
+     * Gets the next value that will be returned by generate().
+     *
+     * @return integer|float
+     */
+    public function getNextValue()
+    {
+        return $this->_nextValue;
+    }
+
+    public function serialize()
+    {
+        return serialize(array(
+            'allocationSize' => $this->_allocationSize,
+            'sequenceName'   => $this->_sequenceName
+        ));
+    }
+
+    public function unserialize($serialized)
+    {
+        $array = unserialize($serialized);
+
+        $this->_sequenceName = $array['sequenceName'];
+        $this->_allocationSize = $array['allocationSize'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/TableGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/TableGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Id/TableGenerator.php	(revision 345)
@@ -0,0 +1,81 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Id;
+
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Id generator that uses a single-row database table and a hi/lo algorithm.
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class TableGenerator extends AbstractIdGenerator
+{
+    private $_tableName;
+    private $_sequenceName;
+    private $_allocationSize;
+    private $_nextValue;
+    private $_maxValue;
+
+    public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10)
+    {
+        $this->_tableName = $tableName;
+        $this->_sequenceName = $sequenceName;
+        $this->_allocationSize = $allocationSize;
+    }
+
+    public function generate(EntityManager $em, $entity)
+    {
+        if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
+            // Allocate new values
+            $conn = $em->getConnection();
+
+            if ($conn->getTransactionNestingLevel() === 0) {
+                // use select for update
+                $sql          = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
+                $currentLevel = $conn->fetchColumn($sql);
+
+                if ($currentLevel != null) {
+                    $this->_nextValue = $currentLevel;
+                    $this->_maxValue = $this->_nextValue + $this->_allocationSize;
+
+                    $updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
+                        $this->_tableName, $this->_sequenceName, $this->_allocationSize
+                    );
+
+                    if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
+                        // no affected rows, concurrency issue, throw exception
+                    }
+                } else {
+                    // no current level returned, TableGenerator seems to be broken, throw exception
+                }
+            } else {
+                // only table locks help here, implement this or throw exception?
+                // or do we want to work with table locks exclusively?
+            }
+        }
+
+        return $this->_nextValue++;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/CommitOrderCalculator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/CommitOrderCalculator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/CommitOrderCalculator.php	(revision 345)
@@ -0,0 +1,118 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal;
+
+/**
+ * The CommitOrderCalculator is used by the UnitOfWork to sort out the
+ * correct order in which changes to entities need to be persisted.
+ *
+ * @since 	2.0
+ * @author 	Roman Borschel <roman@code-factory.org>
+ * @author	Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class CommitOrderCalculator
+{
+    const NOT_VISITED = 1;
+    const IN_PROGRESS = 2;
+    const VISITED = 3;
+
+    private $_nodeStates = array();
+    private $_classes = array(); // The nodes to sort
+    private $_relatedClasses = array();
+    private $_sorted = array();
+
+    /**
+     * Clears the current graph.
+     *
+     * @return void
+     */
+    public function clear()
+    {
+        $this->_classes =
+        $this->_relatedClasses = array();
+    }
+
+    /**
+     * Gets a valid commit order for all current nodes.
+     *
+     * Uses a depth-first search (DFS) to traverse the graph.
+     * The desired topological sorting is the reverse postorder of these searches.
+     *
+     * @return array The list of ordered classes.
+     */
+    public function getCommitOrder()
+    {
+        // Check whether we need to do anything. 0 or 1 node is easy.
+        $nodeCount = count($this->_classes);
+
+        if ($nodeCount <= 1) {
+            return ($nodeCount == 1) ? array_values($this->_classes) : array();
+        }
+
+        // Init
+        foreach ($this->_classes as $node) {
+            $this->_nodeStates[$node->name] = self::NOT_VISITED;
+        }
+
+        // Go
+        foreach ($this->_classes as $node) {
+            if ($this->_nodeStates[$node->name] == self::NOT_VISITED) {
+                $this->_visitNode($node);
+            }
+        }
+
+        $sorted = array_reverse($this->_sorted);
+
+        $this->_sorted = $this->_nodeStates = array();
+
+        return $sorted;
+    }
+
+    private function _visitNode($node)
+    {
+        $this->_nodeStates[$node->name] = self::IN_PROGRESS;
+
+        if (isset($this->_relatedClasses[$node->name])) {
+            foreach ($this->_relatedClasses[$node->name] as $relatedNode) {
+                if ($this->_nodeStates[$relatedNode->name] == self::NOT_VISITED) {
+                    $this->_visitNode($relatedNode);
+                }
+            }
+        }
+
+        $this->_nodeStates[$node->name] = self::VISITED;
+        $this->_sorted[] = $node;
+    }
+
+    public function addDependency($fromClass, $toClass)
+    {
+        $this->_relatedClasses[$fromClass->name][] = $toClass;
+    }
+
+    public function hasClass($className)
+    {
+        return isset($this->_classes[$className]);
+    }
+
+    public function addClass($class)
+    {
+        $this->_classes[$class->name] = $class;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php	(revision 345)
@@ -0,0 +1,389 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use PDO,
+    Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\EntityManager,
+    Doctrine\ORM\Events,
+    Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * Base class for all hydrators. A hydrator is a class that provides some form
+ * of transformation of an SQL result set into another structure.
+ *
+ * @since  2.0
+ * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
+ */
+abstract class AbstractHydrator
+{
+    /** @var ResultSetMapping The ResultSetMapping. */
+    protected $_rsm;
+
+    /** @var EntityManager The EntityManager instance. */
+    protected $_em;
+
+    /** @var AbstractPlatform The dbms Platform instance */
+    protected $_platform;
+
+    /** @var UnitOfWork The UnitOfWork of the associated EntityManager. */
+    protected $_uow;
+
+    /** @var array The cache used during row-by-row hydration. */
+    protected $_cache = array();
+
+    /** @var Statement The statement that provides the data to hydrate. */
+    protected $_stmt;
+
+    /** @var array The query hints. */
+    protected $_hints;
+
+    /**
+     * Initializes a new instance of a class derived from <tt>AbstractHydrator</tt>.
+     *
+     * @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em       = $em;
+        $this->_platform = $em->getConnection()->getDatabasePlatform();
+        $this->_uow      = $em->getUnitOfWork();
+    }
+
+    /**
+     * Initiates a row-by-row hydration.
+     *
+     * @param object $stmt
+     * @param object $resultSetMapping
+     *
+     * @return IterableResult
+     */
+    public function iterate($stmt, $resultSetMapping, array $hints = array())
+    {
+        $this->_stmt  = $stmt;
+        $this->_rsm   = $resultSetMapping;
+        $this->_hints = $hints;
+
+        $evm = $this->_em->getEventManager();
+        $evm->addEventListener(array(Events::onClear), $this);
+
+        $this->prepare();
+
+        return new IterableResult($this);
+    }
+
+    /**
+     * Hydrates all rows returned by the passed statement instance at once.
+     *
+     * @param object $stmt
+     * @param object $resultSetMapping
+     * @return mixed
+     */
+    public function hydrateAll($stmt, $resultSetMapping, array $hints = array())
+    {
+        $this->_stmt  = $stmt;
+        $this->_rsm   = $resultSetMapping;
+        $this->_hints = $hints;
+
+        $this->prepare();
+
+        $result = $this->hydrateAllData();
+
+        $this->cleanup();
+
+        return $result;
+    }
+
+    /**
+     * Hydrates a single row returned by the current statement instance during
+     * row-by-row hydration with {@link iterate()}.
+     *
+     * @return mixed
+     */
+    public function hydrateRow()
+    {
+        $row = $this->_stmt->fetch(PDO::FETCH_ASSOC);
+
+        if ( ! $row) {
+            $this->cleanup();
+
+            return false;
+        }
+
+        $result = array();
+
+        $this->hydrateRowData($row, $this->_cache, $result);
+
+        return $result;
+    }
+
+    /**
+     * Excutes one-time preparation tasks, once each time hydration is started
+     * through {@link hydrateAll} or {@link iterate()}.
+     */
+    protected function prepare()
+    {}
+
+    /**
+     * Excutes one-time cleanup tasks at the end of a hydration that was initiated
+     * through {@link hydrateAll} or {@link iterate()}.
+     */
+    protected function cleanup()
+    {
+        $this->_rsm = null;
+
+        $this->_stmt->closeCursor();
+        $this->_stmt = null;
+    }
+
+    /**
+     * Hydrates a single row from the current statement instance.
+     *
+     * Template method.
+     *
+     * @param array $data The row data.
+     * @param array $cache The cache to use.
+     * @param mixed $result The result to fill.
+     */
+    protected function hydrateRowData(array $data, array &$cache, array &$result)
+    {
+        throw new HydrationException("hydrateRowData() not implemented by this hydrator.");
+    }
+
+    /**
+     * Hydrates all rows from the current statement instance at once.
+     */
+    abstract protected function hydrateAllData();
+
+    /**
+     * Processes a row of the result set.
+     *
+     * Used for identity-based hydration (HYDRATE_OBJECT and HYDRATE_ARRAY).
+     * Puts the elements of a result row into a new array, grouped by the dql alias
+     * they belong to. The column names in the result set are mapped to their
+     * field names during this procedure as well as any necessary conversions on
+     * the values applied. Scalar values are kept in a specfic key 'scalars'.
+     *
+     * @param array $data SQL Result Row
+     * @param array &$cache Cache for column to field result information
+     * @param array &$id Dql-Alias => ID-Hash
+     * @param array &$nonemptyComponents Does this DQL-Alias has at least one non NULL value?
+     *
+     * @return array  An array with all the fields (name => value) of the data row,
+     *                grouped by their component alias.
+     */
+    protected function gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
+    {
+        $rowData = array();
+
+        foreach ($data as $key => $value) {
+            // Parse each column name only once. Cache the results.
+            if ( ! isset($cache[$key])) {
+                switch (true) {
+                    // NOTE: Most of the times it's a field mapping, so keep it first!!!
+                    case (isset($this->_rsm->fieldMappings[$key])):
+                        $fieldName     = $this->_rsm->fieldMappings[$key];
+                        $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
+
+                        $cache[$key]['fieldName']    = $fieldName;
+                        $cache[$key]['type']         = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
+                        $cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
+                        $cache[$key]['dqlAlias']     = $this->_rsm->columnOwnerMap[$key];
+                        break;
+
+                    case (isset($this->_rsm->scalarMappings[$key])):
+                        $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
+                        $cache[$key]['type']      = Type::getType($this->_rsm->typeMappings[$key]);
+                        $cache[$key]['isScalar']  = true;
+                        break;
+
+                    case (isset($this->_rsm->metaMappings[$key])):
+                        // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
+                        $fieldName     = $this->_rsm->metaMappings[$key];
+                        $classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$this->_rsm->columnOwnerMap[$key]]);
+
+                        $cache[$key]['isMetaColumn'] = true;
+                        $cache[$key]['fieldName']    = $fieldName;
+                        $cache[$key]['dqlAlias']     = $this->_rsm->columnOwnerMap[$key];
+                        $cache[$key]['isIdentifier'] = isset($this->_rsm->isIdentifierColumn[$cache[$key]['dqlAlias']][$key]);
+                        break;
+
+                    default:
+                        // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
+                        // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
+                        continue 2;
+                }
+            }
+
+            if (isset($cache[$key]['isScalar'])) {
+                $value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
+
+                $rowData['scalars'][$cache[$key]['fieldName']] = $value;
+
+                continue;
+            }
+
+            $dqlAlias = $cache[$key]['dqlAlias'];
+
+            if ($cache[$key]['isIdentifier']) {
+                $id[$dqlAlias] .= '|' . $value;
+            }
+
+            if (isset($cache[$key]['isMetaColumn'])) {
+                if ( ! isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value !== null) {
+                    $rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
+                    if ($cache[$key]['isIdentifier']) {
+                        $nonemptyComponents[$dqlAlias] = true;
+                    }
+                }
+
+                continue;
+            }
+
+            // in an inheritance hierarchy the same field could be defined several times.
+            // We overwrite this value so long we dont have a non-null value, that value we keep.
+            // Per definition it cannot be that a field is defined several times and has several values.
+            if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) {
+                continue;
+            }
+
+            $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
+
+            if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
+                $nonemptyComponents[$dqlAlias] = true;
+            }
+        }
+
+        return $rowData;
+    }
+
+    /**
+     * Processes a row of the result set.
+     *
+     * Used for HYDRATE_SCALAR. This is a variant of _gatherRowData() that
+     * simply converts column names to field names and properly converts the
+     * values according to their types. The resulting row has the same number
+     * of elements as before.
+     *
+     * @param array $data
+     * @param array $cache
+     *
+     * @return array The processed row.
+     */
+    protected function gatherScalarRowData(&$data, &$cache)
+    {
+        $rowData = array();
+
+        foreach ($data as $key => $value) {
+            // Parse each column name only once. Cache the results.
+            if ( ! isset($cache[$key])) {
+                switch (true) {
+                    // NOTE: During scalar hydration, most of the times it's a scalar mapping, keep it first!!!
+                    case (isset($this->_rsm->scalarMappings[$key])):
+                        $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
+                        $cache[$key]['isScalar']  = true;
+                        break;
+
+                    case (isset($this->_rsm->fieldMappings[$key])):
+                        $fieldName     = $this->_rsm->fieldMappings[$key];
+                        $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
+
+                        $cache[$key]['fieldName'] = $fieldName;
+                        $cache[$key]['type']      = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
+                        $cache[$key]['dqlAlias']  = $this->_rsm->columnOwnerMap[$key];
+                        break;
+
+                    case (isset($this->_rsm->metaMappings[$key])):
+                        // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
+                        $cache[$key]['isMetaColumn'] = true;
+                        $cache[$key]['fieldName']    = $this->_rsm->metaMappings[$key];
+                        $cache[$key]['dqlAlias']     = $this->_rsm->columnOwnerMap[$key];
+                        break;
+
+                    default:
+                        // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
+                        // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
+                        continue 2;
+                }
+            }
+
+            $fieldName = $cache[$key]['fieldName'];
+
+            switch (true) {
+                case (isset($cache[$key]['isScalar'])):
+                    $rowData[$fieldName] = $value;
+                    break;
+
+                case (isset($cache[$key]['isMetaColumn'])):
+                    $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
+                    break;
+
+                default:
+                    $value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
+
+                    $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
+            }
+        }
+
+        return $rowData;
+    }
+
+    /**
+     * Register entity as managed in UnitOfWork.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     * @param object $entity
+     * @param array $data
+     *
+     * @todo The "$id" generation is the same of UnitOfWork#createEntity. Remove this duplication somehow
+     */
+    protected function registerManaged(ClassMetadata $class, $entity, array $data)
+    {
+        if ($class->isIdentifierComposite) {
+            $id = array();
+            foreach ($class->identifier as $fieldName) {
+                if (isset($class->associationMappings[$fieldName])) {
+                    $id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']];
+                } else {
+                    $id[$fieldName] = $data[$fieldName];
+                }
+            }
+        } else {
+            if (isset($class->associationMappings[$class->identifier[0]])) {
+                $id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]);
+            } else {
+                $id = array($class->identifier[0] => $data[$class->identifier[0]]);
+            }
+        }
+
+        $this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
+    }
+
+    /**
+     * When executed in a hydrate() loop we have to clear internal state to
+     * decrease memory consumption.
+     */
+    public function onClear($eventArgs)
+    {
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php	(revision 345)
@@ -0,0 +1,289 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use PDO, Doctrine\DBAL\Connection, Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * The ArrayHydrator produces a nested array "graph" that is often (not always)
+ * interchangeable with the corresponding object graph for read-only access.
+ *
+ * @since  2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
+ */
+class ArrayHydrator extends AbstractHydrator
+{
+    private $_ce = array();
+    private $_rootAliases = array();
+    private $_isSimpleQuery = false;
+    private $_identifierMap = array();
+    private $_resultPointers = array();
+    private $_idTemplate = array();
+    private $_resultCounter = 0;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function prepare()
+    {
+        $this->_isSimpleQuery  = count($this->_rsm->aliasMap) <= 1;
+        $this->_identifierMap  = array();
+        $this->_resultPointers = array();
+        $this->_idTemplate     = array();
+        $this->_resultCounter  = 0;
+
+        foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
+            $this->_identifierMap[$dqlAlias]  = array();
+            $this->_resultPointers[$dqlAlias] = array();
+            $this->_idTemplate[$dqlAlias]     = '';
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateAllData()
+    {
+        $result = array();
+        $cache  = array();
+
+        while ($data = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
+            $this->hydrateRowData($data, $cache, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateRowData(array $row, array &$cache, array &$result)
+    {
+        // 1) Initialize
+        $id = $this->_idTemplate; // initialize the id-memory
+        $nonemptyComponents = array();
+        $rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
+
+        // Extract scalar values. They're appended at the end.
+        if (isset($rowData['scalars'])) {
+            $scalars = $rowData['scalars'];
+
+            unset($rowData['scalars']);
+
+            if (empty($rowData)) {
+                ++$this->_resultCounter;
+            }
+        }
+
+        // 2) Now hydrate the data found in the current row.
+        foreach ($rowData as $dqlAlias => $data) {
+            $index = false;
+
+            if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
+                // It's a joined result
+
+                $parent = $this->_rsm->parentAliasMap[$dqlAlias];
+                $path   = $parent . '.' . $dqlAlias;
+
+                // missing parent data, skipping as RIGHT JOIN hydration is not supported.
+                if ( ! isset($nonemptyComponents[$parent]) ) {
+                    continue;
+                }
+
+                // Get a reference to the right element in the result tree.
+                // This element will get the associated element attached.
+                if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) {
+                	$first = reset($this->_resultPointers);
+                    // TODO: Exception if $key === null ?
+                    $baseElement =& $this->_resultPointers[$parent][key($first)];
+                } else if (isset($this->_resultPointers[$parent])) {
+                    $baseElement =& $this->_resultPointers[$parent];
+                } else {
+                    unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
+                    continue;
+                }
+
+                $relationAlias = $this->_rsm->relationMap[$dqlAlias];
+                $relation = $this->getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias];
+
+                // Check the type of the relation (many or single-valued)
+                if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
+                    $oneToOne = false;
+
+                    if (isset($nonemptyComponents[$dqlAlias])) {
+                        if ( ! isset($baseElement[$relationAlias])) {
+                            $baseElement[$relationAlias] = array();
+                        }
+
+                        $indexExists  = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
+                        $index        = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
+                        $indexIsValid = $index !== false ? isset($baseElement[$relationAlias][$index]) : false;
+
+                        if ( ! $indexExists || ! $indexIsValid) {
+                            $element = $data;
+                            if (isset($this->_rsm->indexByMap[$dqlAlias])) {
+                                $baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element;
+                            } else {
+                                $baseElement[$relationAlias][] = $element;
+                            }
+
+                            end($baseElement[$relationAlias]);
+
+                            $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = key($baseElement[$relationAlias]);
+                        }
+                    } else if ( ! isset($baseElement[$relationAlias])) {
+                        $baseElement[$relationAlias] = array();
+                    }
+                } else {
+                    $oneToOne = true;
+
+                    if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) {
+                        $baseElement[$relationAlias] = null;
+                    } else if ( ! isset($baseElement[$relationAlias])) {
+                        $baseElement[$relationAlias] = $data;
+                    }
+                }
+
+                $coll =& $baseElement[$relationAlias];
+
+                if ($coll !== null) {
+                    $this->updateResultPointer($coll, $index, $dqlAlias, $oneToOne);
+                }
+
+            } else {
+                // It's a root result element
+
+                $this->_rootAliases[$dqlAlias] = true; // Mark as root
+                $entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
+
+                // if this row has a NULL value for the root result id then make it a null result.
+                if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
+                    if ($this->_rsm->isMixed) {
+                        $result[] = array($entityKey => null);
+                    } else {
+                        $result[] = null;
+                    }
+                    $resultKey = $this->_resultCounter;
+                    ++$this->_resultCounter;
+                    continue;
+                }
+
+                // Check for an existing element
+                if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
+                    $element = $rowData[$dqlAlias];
+                    if ($this->_rsm->isMixed) {
+                        $element = array($entityKey => $element);
+                    }
+
+                    if (isset($this->_rsm->indexByMap[$dqlAlias])) {
+                        $resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
+                        $result[$resultKey] = $element;
+                    } else {
+                        $resultKey = $this->_resultCounter;
+                        $result[] = $element;
+                        ++$this->_resultCounter;
+                    }
+
+                    $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
+                } else {
+                    $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
+                    $resultKey = $index;
+                    /*if ($this->_rsm->isMixed) {
+                        $result[] =& $result[$index];
+                        ++$this->_resultCounter;
+                    }*/
+                }
+                $this->updateResultPointer($result, $index, $dqlAlias, false);
+            }
+        }
+
+        // Append scalar values to mixed result sets
+        if (isset($scalars)) {
+            if ( ! isset($resultKey) ) {
+                // this only ever happens when no object is fetched (scalar result only)
+                if (isset($this->_rsm->indexByMap['scalars'])) {
+                    $resultKey = $row[$this->_rsm->indexByMap['scalars']];
+                } else {
+                    $resultKey = $this->_resultCounter - 1;
+                }
+            }
+
+            foreach ($scalars as $name => $value) {
+                $result[$resultKey][$name] = $value;
+            }
+        }
+    }
+
+    /**
+     * Updates the result pointer for an Entity. The result pointers point to the
+     * last seen instance of each Entity type. This is used for graph construction.
+     *
+     * @param array $coll  The element.
+     * @param boolean|integer $index  Index of the element in the collection.
+     * @param string $dqlAlias
+     * @param boolean $oneToOne  Whether it is a single-valued association or not.
+     */
+    private function updateResultPointer(array &$coll, $index, $dqlAlias, $oneToOne)
+    {
+        if ($coll === null) {
+            unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
+
+            return;
+        }
+
+        if ($index !== false) {
+            $this->_resultPointers[$dqlAlias] =& $coll[$index];
+
+            return;
+        }
+
+        if ( ! $coll) {
+            return;
+        }
+
+        if ($oneToOne) {
+            $this->_resultPointers[$dqlAlias] =& $coll;
+
+            return;
+        }
+
+        end($coll);
+        $this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
+
+        return;
+    }
+
+    /**
+     * Retrieve ClassMetadata associated to entity class name.
+     *
+     * @param string $className
+     *
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    private function getClassMetadata($className)
+    {
+        if ( ! isset($this->_ce[$className])) {
+            $this->_ce[$className] = $this->_em->getClassMetadata($className);
+        }
+
+        return $this->_ce[$className];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/HydrationException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/HydrationException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/HydrationException.php	(revision 345)
@@ -0,0 +1,26 @@
+<?php
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+class HydrationException extends \Doctrine\ORM\ORMException
+{
+    public static function nonUniqueResult()
+    {
+        return new self("The result returned by the query was not unique.");
+    }
+
+    public static function parentObjectOfRelationNotFound($alias, $parentAlias)
+    {
+        return new self("The parent object of entity result with alias '$alias' was not found."
+                . " The parent alias is '$parentAlias'.");
+    }
+
+    public static function emptyDiscriminatorValue($dqlAlias)
+    {
+        return new self("The DQL alias '" . $dqlAlias . "' contains an entity ".
+            "of an inheritance hierachy with an empty discriminator value. This means " .
+            "that the database contains inconsistent data with an empty " .
+            "discriminator value in a table row."
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/IterableResult.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/IterableResult.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/IterableResult.php	(revision 345)
@@ -0,0 +1,104 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+/**
+ * Represents a result structure that can be iterated over, hydrating row-by-row
+ * during the iteration. An IterableResult is obtained by AbstractHydrator#iterate().
+ *
+ * @author robo
+ * @since 2.0
+ */
+class IterableResult implements \Iterator
+{
+    /**
+     * @var \Doctrine\ORM\Internal\Hydration\AbstractHydrator
+     */
+    private $_hydrator;
+
+    /**
+     * @var boolean
+     */
+    private $_rewinded = false;
+
+    /**
+     * @var integer
+     */
+    private $_key = -1;
+
+    /**
+     * @var object
+     */
+    private $_current = null;
+
+    /**
+     * @param \Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator
+     */
+    public function __construct($hydrator)
+    {
+        $this->_hydrator = $hydrator;
+    }
+
+    public function rewind()
+    {
+        if ($this->_rewinded == true) {
+            throw new HydrationException("Can only iterate a Result once.");
+        } else {
+            $this->_current = $this->next();
+            $this->_rewinded = true;
+        }
+    }
+
+    /**
+     * Gets the next set of results.
+     *
+     * @return array
+     */
+    public function next()
+    {
+        $this->_current = $this->_hydrator->hydrateRow();
+        $this->_key++;
+        return $this->_current;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function current()
+    {
+        return $this->_current;
+    }
+
+    /**
+     * @return int
+     */
+    public function key()
+    {
+        return $this->_key;
+    }
+
+    /**
+     * @return bool
+     */
+    public function valid()
+    {
+        return ($this->_current!=false);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php	(revision 345)
@@ -0,0 +1,536 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use PDO,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\PersistentCollection,
+    Doctrine\ORM\Query,
+    Doctrine\ORM\Event\LifecycleEventArgs,
+    Doctrine\ORM\Events,
+    Doctrine\Common\Collections\ArrayCollection,
+    Doctrine\Common\Collections\Collection,
+    Doctrine\ORM\Proxy\Proxy;
+
+/**
+ * The ObjectHydrator constructs an object graph out of an SQL result set.
+ *
+ * @since  2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
+ *
+ * @internal Highly performance-sensitive code.
+ */
+class ObjectHydrator extends AbstractHydrator
+{
+    /* Local ClassMetadata cache to avoid going to the EntityManager all the time.
+     * This local cache is maintained between hydration runs and not cleared.
+     */
+    private $_ce = array();
+
+    /* The following parts are reinitialized on every hydration run. */
+
+    private $_identifierMap;
+    private $_resultPointers;
+    private $_idTemplate;
+    private $_resultCounter;
+    private $_rootAliases = array();
+    private $_initializedCollections = array();
+    private $_existingCollections = array();
+
+
+    /** @override */
+    protected function prepare()
+    {
+        $this->_identifierMap =
+        $this->_resultPointers =
+        $this->_idTemplate = array();
+
+        $this->_resultCounter = 0;
+
+        if ( ! isset($this->_hints['deferEagerLoad'])) {
+            $this->_hints['deferEagerLoad'] = true;
+        }
+
+        foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
+            $this->_identifierMap[$dqlAlias] = array();
+            $this->_idTemplate[$dqlAlias]    = '';
+
+            if ( ! isset($this->_ce[$className])) {
+                $this->_ce[$className] = $this->_em->getClassMetadata($className);
+            }
+
+            // Remember which associations are "fetch joined", so that we know where to inject
+            // collection stubs or proxies and where not.
+            if ( ! isset($this->_rsm->relationMap[$dqlAlias])) {
+                continue;
+            }
+
+            if ( ! isset($this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]])) {
+                throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $this->_rsm->parentAliasMap[$dqlAlias]);
+            }
+
+            $sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
+            $sourceClass     = $this->_getClassMetadata($sourceClassName);
+            $assoc           = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
+
+            $this->_hints['fetched'][$this->_rsm->parentAliasMap[$dqlAlias]][$assoc['fieldName']] = true;
+
+            if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) {
+                continue;
+            }
+
+            // Mark any non-collection opposite sides as fetched, too.
+            if ($assoc['mappedBy']) {
+                $this->_hints['fetched'][$dqlAlias][$assoc['mappedBy']] = true;
+
+                continue;
+            }
+
+            // handle fetch-joined owning side bi-directional one-to-one associations
+            if ($assoc['inversedBy']) {
+                $class        = $this->_ce[$className];
+                $inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
+
+                if ( ! ($inverseAssoc['type'] & ClassMetadata::TO_ONE)) {
+                    continue;
+                }
+
+                $this->_hints['fetched'][$dqlAlias][$inverseAssoc['fieldName']] = true;
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function cleanup()
+    {
+        $eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
+
+        parent::cleanup();
+
+        $this->_identifierMap =
+        $this->_initializedCollections =
+        $this->_existingCollections =
+        $this->_resultPointers = array();
+
+        if ($eagerLoad) {
+            $this->_em->getUnitOfWork()->triggerEagerLoads();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateAllData()
+    {
+        $result = array();
+        $cache  = array();
+
+        while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
+            $this->hydrateRowData($row, $cache, $result);
+        }
+
+        // Take snapshots from all newly initialized collections
+        foreach ($this->_initializedCollections as $coll) {
+            $coll->takeSnapshot();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Initializes a related collection.
+     *
+     * @param object $entity The entity to which the collection belongs.
+     * @param ClassMetadata $class
+     * @param string $name The name of the field on the entity that holds the collection.
+     * @param string $parentDqlAlias Alias of the parent fetch joining this collection.
+     */
+    private function _initRelatedCollection($entity, $class, $fieldName, $parentDqlAlias)
+    {
+        $oid      = spl_object_hash($entity);
+        $relation = $class->associationMappings[$fieldName];
+        $value    = $class->reflFields[$fieldName]->getValue($entity);
+
+        if ($value === null) {
+            $value = new ArrayCollection;
+        }
+
+        if ( ! $value instanceof PersistentCollection) {
+            $value = new PersistentCollection(
+                $this->_em, $this->_ce[$relation['targetEntity']], $value
+            );
+            $value->setOwner($entity, $relation);
+
+            $class->reflFields[$fieldName]->setValue($entity, $value);
+            $this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
+
+            $this->_initializedCollections[$oid . $fieldName] = $value;
+        } else if (
+            isset($this->_hints[Query::HINT_REFRESH]) ||
+            isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) &&
+             ! $value->isInitialized()
+        ) {
+            // Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED!
+            $value->setDirty(false);
+            $value->setInitialized(true);
+            $value->unwrap()->clear();
+
+            $this->_initializedCollections[$oid . $fieldName] = $value;
+        } else {
+            // Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN!
+            $this->_existingCollections[$oid . $fieldName] = $value;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Gets an entity instance.
+     *
+     * @param $data The instance data.
+     * @param $dqlAlias The DQL alias of the entity's class.
+     * @return object The entity.
+     */
+    private function _getEntity(array $data, $dqlAlias)
+    {
+        $className = $this->_rsm->aliasMap[$dqlAlias];
+
+        if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
+            $discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
+
+            if ($data[$discrColumn] === "") {
+                throw HydrationException::emptyDiscriminatorValue($dqlAlias);
+            }
+
+            $className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
+
+            unset($data[$discrColumn]);
+        }
+
+        if (isset($this->_hints[Query::HINT_REFRESH_ENTITY]) && isset($this->_rootAliases[$dqlAlias])) {
+            $this->registerManaged($this->_ce[$className], $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
+        }
+
+        $this->_hints['fetchAlias'] = $dqlAlias;
+
+        return $this->_uow->createEntity($className, $data, $this->_hints);
+    }
+
+    private function _getEntityFromIdentityMap($className, array $data)
+    {
+        // TODO: Abstract this code and UnitOfWork::createEntity() equivalent?
+        $class = $this->_ce[$className];
+
+        /* @var $class ClassMetadata */
+        if ($class->isIdentifierComposite) {
+            $idHash = '';
+            foreach ($class->identifier as $fieldName) {
+                if (isset($class->associationMappings[$fieldName])) {
+                    $idHash .= $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] . ' ';
+                } else {
+                    $idHash .= $data[$fieldName] . ' ';
+                }
+            }
+            return $this->_uow->tryGetByIdHash(rtrim($idHash), $class->rootEntityName);
+        } else if (isset($class->associationMappings[$class->identifier[0]])) {
+            return $this->_uow->tryGetByIdHash($data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']], $class->rootEntityName);
+        } else {
+            return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName);
+        }
+    }
+
+    /**
+     * Gets a ClassMetadata instance from the local cache.
+     * If the instance is not yet in the local cache, it is loaded into the
+     * local cache.
+     *
+     * @param string $className The name of the class.
+     * @return ClassMetadata
+     */
+    private function _getClassMetadata($className)
+    {
+        if ( ! isset($this->_ce[$className])) {
+            $this->_ce[$className] = $this->_em->getClassMetadata($className);
+        }
+
+        return $this->_ce[$className];
+    }
+
+    /**
+     * Hydrates a single row in an SQL result set.
+     *
+     * @internal
+     * First, the data of the row is split into chunks where each chunk contains data
+     * that belongs to a particular component/class. Afterwards, all these chunks
+     * are processed, one after the other. For each chunk of class data only one of the
+     * following code paths is executed:
+     *
+     * Path A: The data chunk belongs to a joined/associated object and the association
+     *         is collection-valued.
+     * Path B: The data chunk belongs to a joined/associated object and the association
+     *         is single-valued.
+     * Path C: The data chunk belongs to a root result element/object that appears in the topmost
+     *         level of the hydrated result. A typical example are the objects of the type
+     *         specified by the FROM clause in a DQL query.
+     *
+     * @param array $data The data of the row to process.
+     * @param array $cache The cache to use.
+     * @param array $result The result array to fill.
+     */
+    protected function hydrateRowData(array $row, array &$cache, array &$result)
+    {
+        // Initialize
+        $id = $this->_idTemplate; // initialize the id-memory
+        $nonemptyComponents = array();
+        // Split the row data into chunks of class data.
+        $rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
+
+        // Extract scalar values. They're appended at the end.
+        if (isset($rowData['scalars'])) {
+            $scalars = $rowData['scalars'];
+
+            unset($rowData['scalars']);
+
+            if (empty($rowData)) {
+                ++$this->_resultCounter;
+            }
+        }
+
+        // Hydrate the data chunks
+        foreach ($rowData as $dqlAlias => $data) {
+            $entityName = $this->_rsm->aliasMap[$dqlAlias];
+
+            if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
+                // It's a joined result
+
+                $parentAlias = $this->_rsm->parentAliasMap[$dqlAlias];
+                // we need the $path to save into the identifier map which entities were already
+                // seen for this parent-child relationship
+                $path = $parentAlias . '.' . $dqlAlias;
+
+                // We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs
+                if (!isset($nonemptyComponents[$parentAlias])) {
+                    // TODO: Add special case code where we hydrate the right join objects into identity map at least
+                    continue;
+                }
+
+                // Get a reference to the parent object to which the joined element belongs.
+                if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) {
+                    $first = reset($this->_resultPointers);
+                    $parentObject = $first[key($first)];
+                } else if (isset($this->_resultPointers[$parentAlias])) {
+                    $parentObject = $this->_resultPointers[$parentAlias];
+                } else {
+                    // Parent object of relation not found, so skip it.
+                    continue;
+                }
+
+                $parentClass = $this->_ce[$this->_rsm->aliasMap[$parentAlias]];
+                $oid = spl_object_hash($parentObject);
+                $relationField = $this->_rsm->relationMap[$dqlAlias];
+                $relation = $parentClass->associationMappings[$relationField];
+                $reflField = $parentClass->reflFields[$relationField];
+
+                // Check the type of the relation (many or single-valued)
+                if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
+                    $reflFieldValue = $reflField->getValue($parentObject);
+                    // PATH A: Collection-valued association
+                    if (isset($nonemptyComponents[$dqlAlias])) {
+                        $collKey = $oid . $relationField;
+                        if (isset($this->_initializedCollections[$collKey])) {
+                            $reflFieldValue = $this->_initializedCollections[$collKey];
+                        } else if ( ! isset($this->_existingCollections[$collKey])) {
+                            $reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
+                        }
+
+                        $indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
+                        $index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
+                        $indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
+
+                        if ( ! $indexExists || ! $indexIsValid) {
+                            if (isset($this->_existingCollections[$collKey])) {
+                                // Collection exists, only look for the element in the identity map.
+                                if ($element = $this->_getEntityFromIdentityMap($entityName, $data)) {
+                                    $this->_resultPointers[$dqlAlias] = $element;
+                                } else {
+                                    unset($this->_resultPointers[$dqlAlias]);
+                                }
+                            } else {
+                                $element = $this->_getEntity($data, $dqlAlias);
+
+                                if (isset($this->_rsm->indexByMap[$dqlAlias])) {
+                                    $indexValue = $row[$this->_rsm->indexByMap[$dqlAlias]];
+                                    $reflFieldValue->hydrateSet($indexValue, $element);
+                                    $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
+                                } else {
+                                    $reflFieldValue->hydrateAdd($element);
+                                    $reflFieldValue->last();
+                                    $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key();
+                                }
+                                // Update result pointer
+                                $this->_resultPointers[$dqlAlias] = $element;
+                            }
+                        } else {
+                            // Update result pointer
+                            $this->_resultPointers[$dqlAlias] = $reflFieldValue[$index];
+                        }
+                    } else if ( ! $reflFieldValue) {
+                        $reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
+                    } else if ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) {
+                        $reflFieldValue->setInitialized(true);
+                    }
+
+                } else {
+                    // PATH B: Single-valued association
+                    $reflFieldValue = $reflField->getValue($parentObject);
+                    if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && !$reflFieldValue->__isInitialized__)) {
+                        // we only need to take action if this value is null,
+                        // we refresh the entity or its an unitialized proxy.
+                        if (isset($nonemptyComponents[$dqlAlias])) {
+                            $element = $this->_getEntity($data, $dqlAlias);
+                            $reflField->setValue($parentObject, $element);
+                            $this->_uow->setOriginalEntityProperty($oid, $relationField, $element);
+                            $targetClass = $this->_ce[$relation['targetEntity']];
+
+                            if ($relation['isOwningSide']) {
+                                //TODO: Just check hints['fetched'] here?
+                                // If there is an inverse mapping on the target class its bidirectional
+                                if ($relation['inversedBy']) {
+                                    $inverseAssoc = $targetClass->associationMappings[$relation['inversedBy']];
+                                    if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) {
+                                        $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($element, $parentObject);
+                                        $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $inverseAssoc['fieldName'], $parentObject);
+                                    }
+                                } else if ($parentClass === $targetClass && $relation['mappedBy']) {
+                                    // Special case: bi-directional self-referencing one-one on the same class
+                                    $targetClass->reflFields[$relationField]->setValue($element, $parentObject);
+                                }
+                            } else {
+                                // For sure bidirectional, as there is no inverse side in unidirectional mappings
+                                $targetClass->reflFields[$relation['mappedBy']]->setValue($element, $parentObject);
+                                $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation['mappedBy'], $parentObject);
+                            }
+                            // Update result pointer
+                            $this->_resultPointers[$dqlAlias] = $element;
+                        } else {
+                            $this->_uow->setOriginalEntityProperty($oid, $relationField, null);
+                        }
+                        // else leave $reflFieldValue null for single-valued associations
+                    } else {
+                        // Update result pointer
+                        $this->_resultPointers[$dqlAlias] = $reflFieldValue;
+                    }
+                }
+            } else {
+                // PATH C: Its a root result element
+                $this->_rootAliases[$dqlAlias] = true; // Mark as root alias
+                $entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
+
+                // if this row has a NULL value for the root result id then make it a null result.
+                if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
+                    if ($this->_rsm->isMixed) {
+                        $result[] = array($entityKey => null);
+                    } else {
+                        $result[] = null;
+                    }
+                    $resultKey = $this->_resultCounter;
+                    ++$this->_resultCounter;
+                    continue;
+                }
+
+                // check for existing result from the iterations before
+                if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
+                    $element = $this->_getEntity($rowData[$dqlAlias], $dqlAlias);
+                    if ($this->_rsm->isMixed) {
+                        $element = array($entityKey => $element);
+                    }
+
+                    if (isset($this->_rsm->indexByMap[$dqlAlias])) {
+                        $resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
+
+                        if (isset($this->_hints['collection'])) {
+                            $this->_hints['collection']->hydrateSet($resultKey, $element);
+                        }
+
+                        $result[$resultKey] = $element;
+                    } else {
+                        $resultKey = $this->_resultCounter;
+                        ++$this->_resultCounter;
+
+                        if (isset($this->_hints['collection'])) {
+                            $this->_hints['collection']->hydrateAdd($element);
+                        }
+
+                        $result[] = $element;
+                    }
+
+                    $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
+
+                    // Update result pointer
+                    $this->_resultPointers[$dqlAlias] = $element;
+
+                } else {
+                    // Update result pointer
+                    $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
+                    $this->_resultPointers[$dqlAlias] = $result[$index];
+                    $resultKey = $index;
+                    /*if ($this->_rsm->isMixed) {
+                        $result[] = $result[$index];
+                        ++$this->_resultCounter;
+                    }*/
+                }
+            }
+        }
+
+        // Append scalar values to mixed result sets
+        if (isset($scalars)) {
+            if ( ! isset($resultKey) ) {
+                if (isset($this->_rsm->indexByMap['scalars'])) {
+                    $resultKey = $row[$this->_rsm->indexByMap['scalars']];
+                } else {
+                    $resultKey = $this->_resultCounter - 1;
+                }
+            }
+
+            foreach ($scalars as $name => $value) {
+                $result[$resultKey][$name] = $value;
+            }
+        }
+    }
+
+    /**
+     * When executed in a hydrate() loop we may have to clear internal state to
+     * decrease memory consumption.
+     */
+    public function onClear($eventArgs)
+    {
+        parent::onClear($eventArgs);
+
+        $aliases              = array_keys($this->_identifierMap);
+        $this->_identifierMap = array();
+
+        foreach ($aliases as $alias) {
+            $this->_identifierMap[$alias] = array();
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * Hydrator that produces flat, rectangular results of scalar data.
+ * The created result is almost the same as a regular SQL result set, except
+ * that column names are mapped to field names and data type conversions take place.
+ *
+ * @since  2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class ScalarHydrator extends AbstractHydrator
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateAllData()
+    {
+        $result = array();
+        $cache  = array();
+
+        while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) {
+            $this->hydrateRowData($data, $cache, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateRowData(array $data, array &$cache, array &$result)
+    {
+        $result[] = $this->gatherScalarRowData($data, $cache);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php	(revision 345)
@@ -0,0 +1,183 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use \PDO,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Event\LifecycleEventArgs,
+    Doctrine\ORM\Events,
+    Doctrine\ORM\Query;
+
+class SimpleObjectHydrator extends AbstractHydrator
+{
+    /**
+     * @var ClassMetadata
+     */
+    private $class;
+
+    /**
+     * @var array
+     */
+    private $declaringClasses = array();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateAllData()
+    {
+        $result = array();
+        $cache = array();
+
+        while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
+            $this->hydrateRowData($row, $cache, $result);
+        }
+
+        $this->_em->getUnitOfWork()->triggerEagerLoads();
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function prepare()
+    {
+        if (count($this->_rsm->aliasMap) !== 1) {
+            throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains more than one object result.");
+        }
+
+        if ($this->_rsm->scalarMappings) {
+            throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains scalar mappings.");
+        }
+
+        $this->class = $this->_em->getClassMetadata(reset($this->_rsm->aliasMap));
+
+        // We only need to add declaring classes if we have inheritance.
+        if ($this->class->inheritanceType === ClassMetadata::INHERITANCE_TYPE_NONE) {
+            return;
+        }
+
+        foreach ($this->_rsm->declaringClasses AS $column => $class) {
+            $this->declaringClasses[$column] = $this->_em->getClassMetadata($class);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateRowData(array $sqlResult, array &$cache, array &$result)
+    {
+        $entityName = $this->class->name;
+        $data       = array();
+
+        // We need to find the correct entity class name if we have inheritance in resultset
+        if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
+            $discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']);
+
+            if ($sqlResult[$discrColumnName] === '') {
+                throw HydrationException::emptyDiscriminatorValue(key($this->_rsm->aliasMap));
+            }
+
+            $entityName = $this->class->discriminatorMap[$sqlResult[$discrColumnName]];
+
+            unset($sqlResult[$discrColumnName]);
+        }
+
+        foreach ($sqlResult as $column => $value) {
+            // Hydrate column information if not yet present
+            if ( ! isset($cache[$column])) {
+                if (($info = $this->hydrateColumnInfo($entityName, $column)) === null) {
+                    continue;
+                }
+
+                $cache[$column] = $info;
+            }
+
+            // Convert field to a valid PHP value
+            if (isset($cache[$column]['field'])) {
+                $type  = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
+                $value = $type->convertToPHPValue($value, $this->_platform);
+            }
+
+            // Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
+            if (isset($cache[$column]) && ( ! isset($data[$cache[$column]['name']]) || $value !== null)) {
+                $data[$cache[$column]['name']] = $value;
+            }
+        }
+
+        if (isset($this->_hints[Query::HINT_REFRESH_ENTITY])) {
+            $this->registerManaged($this->class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
+        }
+
+        $uow    = $this->_em->getUnitOfWork();
+        $entity = $uow->createEntity($entityName, $data, $this->_hints);
+
+        $result[] = $entity;
+    }
+
+    /**
+     * Retrieve column information form ResultSetMapping.
+     *
+     * @param string $entityName
+     * @param string $column
+     *
+     * @return array
+     */
+    protected function hydrateColumnInfo($entityName, $column)
+    {
+        switch (true) {
+            case (isset($this->_rsm->fieldMappings[$column])):
+                $class = isset($this->declaringClasses[$column])
+                    ? $this->declaringClasses[$column]
+                    : $this->class;
+
+                // If class is not part of the inheritance, ignore
+                if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
+                    return null;
+                }
+
+                return array(
+                    'class' => $class,
+                    'name'  => $this->_rsm->fieldMappings[$column],
+                    'field' => true,
+                );
+
+            case (isset($this->_rsm->relationMap[$column])):
+                $class = isset($this->_rsm->relationMap[$column])
+                    ? $this->_rsm->relationMap[$column]
+                    : $this->class;
+
+                // If class is not self referencing, ignore
+                if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
+                    return null;
+                }
+
+                // TODO: Decide what to do with associations. It seems original code is incomplete.
+                // One solution is to load the association, but it might require extra efforts.
+                return array('name' => $column);
+
+            default:
+                return array(
+                    'name' => $this->_rsm->metaMappings[$column]
+                );
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php	(revision 345)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Internal\Hydration;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\ORM\NoResultException,
+    Doctrine\ORM\NonUniqueResultException;
+
+/**
+ * Hydrator that hydrates a single scalar value from the result set.
+ *
+ * @since  2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class SingleScalarHydrator extends AbstractHydrator
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function hydrateAllData()
+    {
+        $data    = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
+        $numRows = count($data);
+
+        if ($numRows === 0) {
+            throw new NoResultException();
+        }
+
+        if ($numRows > 1 || count($data[key($data)]) > 1) {
+            throw new NonUniqueResultException();
+        }
+
+        $cache  = array();
+        $result = $this->gatherScalarRowData($data[key($data)], $cache);
+
+        return array_shift($result);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Annotation.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Annotation.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Annotation.php	(revision 345)
@@ -0,0 +1,24 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+interface Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php	(revision 345)
@@ -0,0 +1,167 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\ORM\Mapping\Builder;
+
+use Doctrine\ORM\Mapping\ClassMetadata;
+
+class AssociationBuilder
+{
+    /**
+     * @var ClassMetadataBuilder
+     */
+    protected $builder;
+
+    /**
+     * @var array
+     */
+    protected $mapping;
+
+    /**
+     * @var array
+     */
+    protected $joinColumns;
+
+    /**
+     *
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * @param ClassMetadataBuilder $builder
+     * @param array $mapping
+     */
+    public function __construct(ClassMetadataBuilder $builder, array $mapping, $type)
+    {
+        $this->builder = $builder;
+        $this->mapping = $mapping;
+        $this->type = $type;
+    }
+
+    public function mappedBy($fieldName)
+    {
+        $this->mapping['mappedBy'] = $fieldName;
+        return $this;
+    }
+
+    public function inversedBy($fieldName)
+    {
+        $this->mapping['inversedBy'] = $fieldName;
+        return $this;
+    }
+
+    public function cascadeAll()
+    {
+        $this->mapping['cascade'] = array("ALL");
+        return $this;
+    }
+
+    public function cascadePersist()
+    {
+        $this->mapping['cascade'][] = "persist";
+        return $this;
+    }
+
+    public function cascadeRemove()
+    {
+        $this->mapping['cascade'][] = "remove";
+        return $this;
+    }
+
+    public function cascadeMerge()
+    {
+        $this->mapping['cascade'][] = "merge";
+        return $this;
+    }
+
+    public function cascadeDetach()
+    {
+        $this->mapping['cascade'][] = "detach";
+        return $this;
+    }
+
+    public function cascadeRefresh()
+    {
+        $this->mapping['cascade'][] = "refresh";
+        return $this;
+    }
+
+    public function fetchExtraLazy()
+    {
+        $this->mapping['fetch'] = ClassMetadata::FETCH_EXTRA_LAZY;
+        return $this;
+    }
+
+    public function fetchEager()
+    {
+        $this->mapping['fetch'] = ClassMetadata::FETCH_EAGER;
+        return $this;
+    }
+
+    public function fetchLazy()
+    {
+        $this->mapping['fetch'] = ClassMetadata::FETCH_LAZY;
+        return $this;
+    }
+
+    /**
+     * Add Join Columns
+     *
+     * @param string $columnName
+     * @param string $referencedColumnName
+     * @param bool $nullable
+     * @param bool $unique
+     * @param string $onDelete
+     * @param string $columnDef
+     */
+    public function addJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
+    {
+        $this->joinColumns[] = array(
+            'name' => $columnName,
+            'referencedColumnName' => $referencedColumnName,
+            'nullable' => $nullable,
+            'unique' => $unique,
+            'onDelete' => $onDelete,
+            'columnDefinition' => $columnDef,
+        );
+        return $this;
+    }
+
+    /**
+     * @return ClassMetadataBuilder
+     */
+    public function build()
+    {
+        $mapping = $this->mapping;
+        if ($this->joinColumns) {
+            $mapping['joinColumns'] = $this->joinColumns;
+        }
+        $cm = $this->builder->getClassMetadata();
+        if ($this->type == ClassMetadata::MANY_TO_ONE) {
+            $cm->mapManyToOne($mapping);
+        } else if ($this->type == ClassMetadata::ONE_TO_ONE) {
+            $cm->mapOneToOne($mapping);
+        } else {
+            throw new \InvalidArgumentException("Type should be a ToOne Assocation here");
+        }
+        return $this->builder;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php	(revision 345)
@@ -0,0 +1,470 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Builder;
+
+use Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * Builder Object for ClassMetadata
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class ClassMetadataBuilder
+{
+    /**
+     * @var \Doctrine\ORM\Mapping\ClassMetadataInfo
+     */
+    private $cm;
+
+    /**
+     * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $cm
+     */
+    public function __construct(ClassMetadataInfo $cm)
+    {
+        $this->cm = $cm;
+    }
+
+    /**
+     * @return ClassMetadata
+     */
+    public function getClassMetadata()
+    {
+        return $this->cm;
+    }
+
+    /**
+     * Mark the class as mapped superclass.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setMappedSuperClass()
+    {
+        $this->cm->isMappedSuperclass = true;
+
+        return $this;
+    }
+
+    /**
+     * Set custom Repository class name
+     *
+     * @param string $repositoryClassName
+     * @return ClassMetadataBuilder
+     */
+    public function setCustomRepositoryClass($repositoryClassName)
+    {
+        $this->cm->setCustomRepositoryClass($repositoryClassName);
+
+        return $this;
+    }
+
+    /**
+     * Mark class read only
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setReadOnly()
+    {
+        $this->cm->markReadOnly();
+
+        return $this;
+    }
+
+    /**
+     * Set the table name
+     *
+     * @param string $name
+     * @return ClassMetadataBuilder
+     */
+    public function setTable($name)
+    {
+        $this->cm->setPrimaryTable(array('name' => $name));
+
+        return $this;
+    }
+
+    /**
+     * Add Index
+     *
+     * @param array $columns
+     * @param string $name
+     * @return ClassMetadataBuilder
+     */
+    public function addIndex(array $columns, $name)
+    {
+        if (!isset($this->cm->table['indexes'])) {
+            $this->cm->table['indexes'] = array();
+        }
+
+        $this->cm->table['indexes'][$name] = array('columns' => $columns);
+
+        return $this;
+    }
+
+    /**
+     * Add Unique Constraint
+     *
+     * @param array $columns
+     * @param string $name
+     * @return ClassMetadataBuilder
+     */
+    public function addUniqueConstraint(array $columns, $name)
+    {
+        if ( ! isset($this->cm->table['uniqueConstraints'])) {
+            $this->cm->table['uniqueConstraints'] = array();
+        }
+
+        $this->cm->table['uniqueConstraints'][$name] = array('columns' => $columns);
+
+        return $this;
+    }
+
+    /**
+     * Add named query
+     *
+     * @param string $name
+     * @param string $dqlQuery
+     * @return ClassMetadataBuilder
+     */
+    public function addNamedQuery($name, $dqlQuery)
+    {
+        $this->cm->addNamedQuery(array(
+            'name' => $name,
+            'query' => $dqlQuery,
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Set class as root of a joined table inheritance hierachy.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setJoinedTableInheritance()
+    {
+        $this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_JOINED);
+
+        return $this;
+    }
+
+    /**
+     * Set class as root of a single table inheritance hierachy.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setSingleTableInheritance()
+    {
+        $this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
+
+        return $this;
+    }
+
+    /**
+     * Set the discriminator column details.
+     *
+     * @param string $name
+     * @param string $type
+     */
+    public function setDiscriminatorColumn($name, $type = 'string', $length = 255)
+    {
+        $this->cm->setDiscriminatorColumn(array(
+            'name' => $name,
+            'type' => $type,
+            'length' => $length,
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Add a subclass to this inheritance hierachy.
+     *
+     * @param string $name
+     * @param string $class
+     * @return ClassMetadataBuilder
+     */
+    public function addDiscriminatorMapClass($name, $class)
+    {
+        $this->cm->addDiscriminatorMapClass($name, $class);
+
+        return $this;
+    }
+
+    /**
+     * Set deferred explicit change tracking policy.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setChangeTrackingPolicyDeferredExplicit()
+    {
+        $this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT);
+
+        return $this;
+    }
+
+    /**
+     * Set notify change tracking policy.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function setChangeTrackingPolicyNotify()
+    {
+        $this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_NOTIFY);
+
+        return $this;
+    }
+
+    /**
+     * Add lifecycle event
+     *
+     * @param string $methodName
+     * @param string $event
+     * @return ClassMetadataBuilder
+     */
+    public function addLifecycleEvent($methodName, $event)
+    {
+        $this->cm->addLifecycleCallback($methodName, $event);
+
+        return $this;
+    }
+
+    /**
+     * Add Field
+     *
+     * @param string $name
+     * @param string $type
+     * @param array $mapping
+     */
+    public function addField($name, $type, array $mapping = array())
+    {
+        $mapping['fieldName'] = $name;
+        $mapping['type'] = $type;
+
+        $this->cm->mapField($mapping);
+
+        return $this;
+    }
+
+    /**
+     * Create a field builder.
+     *
+     * @param string $name
+     * @param string $type
+     * @return FieldBuilder
+     */
+    public function createField($name, $type)
+    {
+        return new FieldBuilder(
+            $this,
+            array(
+                'fieldName' => $name,
+                'type'      => $type
+            )
+        );
+    }
+
+    /**
+     * Add a simple many to one association, optionally with the inversed by field.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string|null $inversedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addManyToOne($name, $targetEntity, $inversedBy = null)
+    {
+        $builder = $this->createManyToOne($name, $targetEntity);
+
+        if ($inversedBy) {
+            $builder->inversedBy($inversedBy);
+        }
+
+        return $builder->build();
+    }
+
+    /**
+     * Create a ManyToOne Assocation Builder.
+     *
+     * Note: This method does not add the association, you have to call build() on the AssociationBuilder.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @return AssociationBuilder
+     */
+    public function createManyToOne($name, $targetEntity)
+    {
+        return new AssociationBuilder(
+            $this,
+            array(
+                'fieldName'    => $name,
+                'targetEntity' => $targetEntity
+            ),
+            ClassMetadata::MANY_TO_ONE
+        );
+    }
+
+    /**
+     * Create OneToOne Assocation Builder
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @return AssociationBuilder
+     */
+    public function createOneToOne($name, $targetEntity)
+    {
+        return new AssociationBuilder(
+            $this,
+            array(
+                'fieldName'    => $name,
+                'targetEntity' => $targetEntity
+            ),
+            ClassMetadata::ONE_TO_ONE
+        );
+    }
+
+    /**
+     * Add simple inverse one-to-one assocation.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string $mappedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addInverseOneToOne($name, $targetEntity, $mappedBy)
+    {
+        $builder = $this->createOneToOne($name, $targetEntity);
+        $builder->mappedBy($mappedBy);
+
+        return $builder->build();
+    }
+
+    /**
+     * Add simple owning one-to-one assocation.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string $inversedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addOwningOneToOne($name, $targetEntity, $inversedBy = null)
+    {
+        $builder = $this->createOneToOne($name, $targetEntity);
+
+        if ($inversedBy) {
+            $builder->inversedBy($inversedBy);
+        }
+
+        return $builder->build();
+    }
+
+    /**
+     * Create ManyToMany Assocation Builder
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @return ManyToManyAssociationBuilder
+     */
+    public function createManyToMany($name, $targetEntity)
+    {
+        return new ManyToManyAssociationBuilder(
+            $this,
+            array(
+                'fieldName'    => $name,
+                'targetEntity' => $targetEntity
+            ),
+            ClassMetadata::MANY_TO_MANY
+        );
+    }
+
+    /**
+     * Add a simple owning many to many assocation.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string|null $inversedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addOwningManyToMany($name, $targetEntity, $inversedBy = null)
+    {
+        $builder = $this->createManyToMany($name, $targetEntity);
+
+        if ($inversedBy) {
+            $builder->inversedBy($inversedBy);
+        }
+
+        return $builder->build();
+    }
+
+    /**
+     * Add a simple inverse many to many assocation.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string $mappedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addInverseManyToMany($name, $targetEntity, $mappedBy)
+    {
+        $builder = $this->createManyToMany($name, $targetEntity);
+        $builder->mappedBy($mappedBy);
+
+        return $builder->build();
+    }
+
+    /**
+     * Create a one to many assocation builder
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @return OneToManyAssociationBuilder
+     */
+    public function createOneToMany($name, $targetEntity)
+    {
+        return new OneToManyAssociationBuilder(
+            $this,
+            array(
+                'fieldName'    => $name,
+                'targetEntity' => $targetEntity
+            ),
+            ClassMetadata::ONE_TO_MANY
+        );
+    }
+
+    /**
+     * Add simple OneToMany assocation.
+     *
+     * @param string $name
+     * @param string $targetEntity
+     * @param string $mappedBy
+     * @return ClassMetadataBuilder
+     */
+    public function addOneToMany($name, $targetEntity, $mappedBy)
+    {
+        $builder = $this->createOneToMany($name, $targetEntity);
+        $builder->mappedBy($mappedBy);
+
+        return $builder->build();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/FieldBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/FieldBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/FieldBuilder.php	(revision 345)
@@ -0,0 +1,223 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\ORM\Mapping\Builder;
+
+/**
+ * Field Builder
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class FieldBuilder
+{
+    /**
+     * @var ClassMetadataBuilder
+     */
+    private $builder;
+    /**
+     * @var array
+     */
+    private $mapping;
+    /**
+     * @var bool
+     */
+    private $version;
+
+    /**
+     * @var string
+     */
+    private $generatedValue;
+
+    /**
+     * @var array
+     */
+    private $sequenceDef;
+
+    /**
+     *
+     * @param ClassMetadataBuilder $builder
+     * @param array $mapping
+     */
+    public function __construct(ClassMetadataBuilder $builder, array $mapping)
+    {
+        $this->builder = $builder;
+        $this->mapping = $mapping;
+    }
+
+    /**
+     * Set length.
+     *
+     * @param int $length
+     * @return FieldBuilder
+     */
+    public function length($length)
+    {
+        $this->mapping['length'] = $length;
+        return $this;
+    }
+
+    /**
+     * Set nullable
+     *
+     * @param bool
+     * @return FieldBuilder
+     */
+    public function nullable($flag = true)
+    {
+        $this->mapping['nullable'] = (bool)$flag;
+        return $this;
+    }
+
+    /**
+     * Set Unique
+     *
+     * @param bool
+     * @return FieldBuilder
+     */
+    public function unique($flag = true)
+    {
+        $this->mapping['unique'] = (bool)$flag;
+        return $this;
+    }
+
+    /**
+     * Set column name
+     *
+     * @param string $name
+     * @return FieldBuilder
+     */
+    public function columnName($name)
+    {
+        $this->mapping['columnName'] = $name;
+        return $this;
+    }
+
+    /**
+     * Set Precision
+     *
+     * @param  int $p
+     * @return FieldBuilder
+     */
+    public function precision($p)
+    {
+        $this->mapping['precision'] = $p;
+        return $this;
+    }
+
+    /**
+     * Set scale.
+     *
+     * @param int $s
+     * @return FieldBuilder
+     */
+    public function scale($s)
+    {
+        $this->mapping['scale'] = $s;
+        return $this;
+    }
+
+    /**
+     * Set field as primary key.
+     *
+     * @return FieldBuilder
+     */
+    public function isPrimaryKey()
+    {
+        $this->mapping['id'] = true;
+        return $this;
+    }
+
+    /**
+     * @param  int $strategy
+     * @return FieldBuilder
+     */
+    public function generatedValue($strategy = 'AUTO')
+    {
+        $this->generatedValue = $strategy;
+        return $this;
+    }
+
+    /**
+     * Set field versioned
+     *
+     * @return FieldBuilder
+     */
+    public function isVersionField()
+    {
+        $this->version = true;
+        return $this;
+    }
+
+    /**
+     * Set Sequence Generator
+     *
+     * @param string $sequenceName
+     * @param int $allocationSize
+     * @param int $initialValue
+     * @return FieldBuilder
+     */
+    public function setSequenceGenerator($sequenceName, $allocationSize = 1, $initialValue = 1)
+    {
+        $this->sequenceDef = array(
+            'sequenceName' => $sequenceName,
+            'allocationSize' => $allocationSize,
+            'initialValue' => $initialValue,
+        );
+        return $this;
+    }
+
+    /**
+     * Set column definition.
+     *
+     * @param string $def
+     * @return FieldBuilder
+     */
+    public function columnDefinition($def)
+    {
+        $this->mapping['columnDefinition'] = $def;
+        return $this;
+    }
+
+    /**
+     * Finalize this field and attach it to the ClassMetadata.
+     *
+     * Without this call a FieldBuilder has no effect on the ClassMetadata.
+     *
+     * @return ClassMetadataBuilder
+     */
+    public function build()
+    {
+        $cm = $this->builder->getClassMetadata();
+        if ($this->generatedValue) {
+            $cm->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $this->generatedValue));
+        }
+        if ($this->version) {
+            $cm->setVersionMapping($this->mapping);
+        }
+        $cm->mapField($this->mapping);
+        if ($this->sequenceDef) {
+            $cm->setSequenceGeneratorDefinition($this->sequenceDef);
+        }
+        return $this->builder;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php	(revision 345)
@@ -0,0 +1,86 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\ORM\Mapping\Builder;
+
+/**
+ * ManyToMany Association Builder
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
+{
+    private $joinTableName;
+
+    private $inverseJoinColumns = array();
+
+    public function setJoinTable($name)
+    {
+        $this->joinTableName = $name;
+        return $this;
+    }
+
+    /**
+     * Add Inverse Join Columns
+     *
+     * @param string $columnName
+     * @param string $referencedColumnName
+     * @param bool $nullable
+     * @param bool $unique
+     * @param string $onDelete
+     * @param string $columnDef
+     */
+    public function addInverseJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
+    {
+        $this->inverseJoinColumns[] = array(
+            'name' => $columnName,
+            'referencedColumnName' => $referencedColumnName,
+            'nullable' => $nullable,
+            'unique' => $unique,
+            'onDelete' => $onDelete,
+            'columnDefinition' => $columnDef,
+        );
+        return $this;
+    }
+
+    /**
+     * @return ClassMetadataBuilder
+     */
+    public function build()
+    {
+        $mapping = $this->mapping;
+        $mapping['joinTable'] = array();
+        if ($this->joinColumns) {
+            $mapping['joinTable']['joinColumns'] = $this->joinColumns;
+        }
+        if ($this->inverseJoinColumns) {
+            $mapping['joinTable']['inverseJoinColumns'] = $this->inverseJoinColumns;
+        }
+        if ($this->joinTableName) {
+            $mapping['joinTable']['name'] = $this->joinTableName;
+        }
+        $cm = $this->builder->getClassMetadata();
+        $cm->mapManyToMany($mapping);
+        return $this->builder;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\ORM\Mapping\Builder;
+
+/**
+ * OneToMany Association Builder
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OneToManyAssociationBuilder extends AssociationBuilder
+{
+    /**
+     * @param array $fieldNames
+     * @return OneToManyAssociationBuilder
+     */
+    public function setOrderBy(array $fieldNames)
+    {
+        $this->mapping['orderBy'] = $fieldNames;
+        return $this;
+    }
+
+    public function setIndexBy($fieldName)
+    {
+        $this->mapping['indexBy'] = $fieldName;
+        return $this;
+    }
+
+    /**
+     * @return ClassMetadataBuilder
+     */
+    public function build()
+    {
+        $mapping = $this->mapping;
+        if ($this->joinColumns) {
+            $mapping['joinColumns'] = $this->joinColumns;
+        }
+        $cm = $this->builder->getClassMetadata();
+        $cm->mapOneToMany($mapping);
+        return $this->builder;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class ChangeTrackingPolicy implements Annotation
+{
+    /** @var string */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadata.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadata.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadata.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+use ReflectionClass, ReflectionProperty;
+
+/**
+ * A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
+ * of an entity and it's associations.
+ *
+ * Once populated, ClassMetadata instances are usually cached in a serialized form.
+ *
+ * <b>IMPORTANT NOTE:</b>
+ *
+ * The fields of this class are only public for 2 reasons:
+ * 1) To allow fast READ access.
+ * 2) To drastically reduce the size of a serialized instance (private/protected members
+ *    get the whole class name, namespace inclusive, prepended to every property in
+ *    the serialized representation).
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @since 2.0
+ */
+class ClassMetadata extends ClassMetadataInfo
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataFactory.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataFactory.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataFactory.php	(revision 345)
@@ -0,0 +1,593 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+use ReflectionException,
+    Doctrine\ORM\ORMException,
+    Doctrine\ORM\EntityManager,
+    Doctrine\DBAL\Platforms,
+    Doctrine\ORM\Events,
+    Doctrine\Common\Persistence\Mapping\RuntimeReflectionService,
+    Doctrine\Common\Persistence\Mapping\ReflectionService,
+    Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as ClassMetadataFactoryInterface;
+
+/**
+ * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
+ * metadata mapping informations of a class which describes how a class should be mapped
+ * to a relational database.
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ClassMetadataFactory implements ClassMetadataFactoryInterface
+{
+    /**
+     * @var EntityManager
+     */
+    private $em;
+
+    /**
+     * @var AbstractPlatform
+     */
+    private $targetPlatform;
+
+    /**
+     * @var \Doctrine\ORM\Mapping\Driver\Driver
+     */
+    private $driver;
+
+    /**
+     * @var \Doctrine\Common\EventManager
+     */
+    private $evm;
+
+    /**
+     * @var \Doctrine\Common\Cache\Cache
+     */
+    private $cacheDriver;
+
+    /**
+     * @var array
+     */
+    private $loadedMetadata = array();
+
+    /**
+     * @var bool
+     */
+    private $initialized = false;
+
+    /**
+     * @var ReflectionService
+     */
+    private $reflectionService;
+
+    /**
+     * @param EntityManager $$em
+     */
+    public function setEntityManager(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Sets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheDriver
+     */
+    public function setCacheDriver($cacheDriver)
+    {
+        $this->cacheDriver = $cacheDriver;
+    }
+
+    /**
+     * Gets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getCacheDriver()
+    {
+        return $this->cacheDriver;
+    }
+
+    public function getLoadedMetadata()
+    {
+        return $this->loadedMetadata;
+    }
+
+    /**
+     * Forces the factory to load the metadata of all classes known to the underlying
+     * mapping driver.
+     *
+     * @return array The ClassMetadata instances of all mapped classes.
+     */
+    public function getAllMetadata()
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $metadata = array();
+        foreach ($this->driver->getAllClassNames() as $className) {
+            $metadata[] = $this->getMetadataFor($className);
+        }
+
+        return $metadata;
+    }
+
+    /**
+     * Lazy initialization of this stuff, especially the metadata driver,
+     * since these are not needed at all when a metadata cache is active.
+     */
+    private function initialize()
+    {
+        $this->driver = $this->em->getConfiguration()->getMetadataDriverImpl();
+        $this->targetPlatform = $this->em->getConnection()->getDatabasePlatform();
+        $this->evm = $this->em->getEventManager();
+        $this->initialized = true;
+    }
+
+    /**
+     * Gets the class metadata descriptor for a class.
+     *
+     * @param string $className The name of the class.
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    public function getMetadataFor($className)
+    {
+        if ( ! isset($this->loadedMetadata[$className])) {
+            $realClassName = $className;
+
+            // Check for namespace alias
+            if (strpos($className, ':') !== false) {
+                list($namespaceAlias, $simpleClassName) = explode(':', $className);
+                $realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
+
+                if (isset($this->loadedMetadata[$realClassName])) {
+                    // We do not have the alias name in the map, include it
+                    $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+
+                    return $this->loadedMetadata[$realClassName];
+                }
+            }
+
+            if ($this->cacheDriver) {
+                if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
+                    $this->wakeupReflection($cached, $this->getReflectionService());
+                    $this->loadedMetadata[$realClassName] = $cached;
+                } else {
+                    foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
+                        $this->cacheDriver->save(
+                            "$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
+                        );
+                    }
+                }
+            } else {
+                $this->loadMetadata($realClassName);
+            }
+
+            if ($className != $realClassName) {
+                // We do not have the alias name in the map, include it
+                $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+            }
+        }
+
+        return $this->loadedMetadata[$className];
+    }
+
+    /**
+     * Checks whether the factory has the metadata for a class loaded already.
+     *
+     * @param string $className
+     * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+     */
+    public function hasMetadataFor($className)
+    {
+        return isset($this->loadedMetadata[$className]);
+    }
+
+    /**
+     * Sets the metadata descriptor for a specific class.
+     *
+     * NOTE: This is only useful in very special cases, like when generating proxy classes.
+     *
+     * @param string $className
+     * @param ClassMetadata $class
+     */
+    public function setMetadataFor($className, $class)
+    {
+        $this->loadedMetadata[$className] = $class;
+    }
+
+    /**
+     * Get array of parent classes for the given entity class
+     *
+     * @param string $name
+     * @return array $parentClasses
+     */
+    protected function getParentClasses($name)
+    {
+        // Collect parent classes, ignoring transient (not-mapped) classes.
+        $parentClasses = array();
+        foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
+            if ( ! $this->driver->isTransient($parentClass)) {
+                $parentClasses[] = $parentClass;
+            }
+        }
+        return $parentClasses;
+    }
+
+    /**
+     * Loads the metadata of the class in question and all it's ancestors whose metadata
+     * is still not loaded.
+     *
+     * @param string $name The name of the class for which the metadata should get loaded.
+     * @param array  $tables The metadata collection to which the loaded metadata is added.
+     */
+    protected function loadMetadata($name)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $loaded = array();
+
+        $parentClasses = $this->getParentClasses($name);
+        $parentClasses[] = $name;
+
+        // Move down the hierarchy of parent classes, starting from the topmost class
+        $parent = null;
+        $rootEntityFound = false;
+        $visited = array();
+        foreach ($parentClasses as $className) {
+            if (isset($this->loadedMetadata[$className])) {
+                $parent = $this->loadedMetadata[$className];
+                if ( ! $parent->isMappedSuperclass) {
+                    $rootEntityFound = true;
+                    array_unshift($visited, $className);
+                }
+                continue;
+            }
+
+            $class = $this->newClassMetadataInstance($className);
+            $this->initializeReflection($class, $this->getReflectionService());
+
+            if ($parent) {
+                $class->setInheritanceType($parent->inheritanceType);
+                $class->setDiscriminatorColumn($parent->discriminatorColumn);
+                $class->setIdGeneratorType($parent->generatorType);
+                $this->addInheritedFields($class, $parent);
+                $this->addInheritedRelations($class, $parent);
+                $class->setIdentifier($parent->identifier);
+                $class->setVersioned($parent->isVersioned);
+                $class->setVersionField($parent->versionField);
+                $class->setDiscriminatorMap($parent->discriminatorMap);
+                $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
+                $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
+                if ($parent->isMappedSuperclass) {
+                    $class->setCustomRepositoryClass($parent->customRepositoryClassName);
+                }
+            }
+
+            // Invoke driver
+            try {
+                $this->driver->loadMetadataForClass($className, $class);
+            } catch (ReflectionException $e) {
+                throw MappingException::reflectionFailure($className, $e);
+            }
+
+            // If this class has a parent the id generator strategy is inherited.
+            // However this is only true if the hierachy of parents contains the root entity,
+            // if it consinsts of mapped superclasses these don't necessarily include the id field.
+            if ($parent && $rootEntityFound) {
+                if ($parent->isIdGeneratorSequence()) {
+                    $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
+                } else if ($parent->isIdGeneratorTable()) {
+                    $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
+                }
+                if ($parent->generatorType) {
+                    $class->setIdGeneratorType($parent->generatorType);
+                }
+                if ($parent->idGenerator) {
+                    $class->setIdGenerator($parent->idGenerator);
+                }
+            } else {
+                $this->completeIdGeneratorMapping($class);
+            }
+
+            if ($parent && $parent->isInheritanceTypeSingleTable()) {
+                $class->setPrimaryTable($parent->table);
+            }
+
+            if ($parent && $parent->containsForeignIdentifier) {
+                $class->containsForeignIdentifier = true;
+            }
+
+            if ($parent && !empty ($parent->namedQueries)) {
+                $this->addInheritedNamedQueries($class, $parent);
+            }
+
+            $class->setParentClasses($visited);
+
+            if ($this->evm->hasListeners(Events::loadClassMetadata)) {
+                $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
+                $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
+            }
+            $this->wakeupReflection($class, $this->getReflectionService());
+
+            $this->validateRuntimeMetadata($class, $parent);
+
+            $this->loadedMetadata[$className] = $class;
+
+            $parent = $class;
+
+            if ( ! $class->isMappedSuperclass) {
+                $rootEntityFound = true;
+                array_unshift($visited, $className);
+            }
+
+            $loaded[] = $className;
+        }
+
+        return $loaded;
+    }
+
+    /**
+     * Validate runtime metadata is correctly defined.
+     *
+     * @param ClassMetadata $class
+     * @param ClassMetadata $parent
+     */
+    protected function validateRuntimeMetadata($class, $parent)
+    {
+        if ( ! $class->reflClass ) {
+            // only validate if there is a reflection class instance
+            return;
+        }
+
+        $class->validateIdentifier();
+        $class->validateAssocations();
+        $class->validateLifecycleCallbacks($this->getReflectionService());
+
+        // verify inheritance
+        if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
+            if (!$parent) {
+                if (count($class->discriminatorMap) == 0) {
+                    throw MappingException::missingDiscriminatorMap($class->name);
+                }
+                if (!$class->discriminatorColumn) {
+                    throw MappingException::missingDiscriminatorColumn($class->name);
+                }
+            } else if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) {
+                // enforce discriminator map for all entities of an inheritance hierachy, otherwise problems will occur.
+                throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
+            }
+        } else if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
+            // second condition is necessary for mapped superclasses in the middle of an inheritance hierachy
+            throw MappingException::noInheritanceOnMappedSuperClass($class->name);
+        }
+    }
+
+    /**
+     * Creates a new ClassMetadata instance for the given class name.
+     *
+     * @param string $className
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    protected function newClassMetadataInstance($className)
+    {
+        return new ClassMetadata($className);
+    }
+
+    /**
+     * Adds inherited fields to the subclass mapping.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
+     */
+    private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
+    {
+        foreach ($parentClass->fieldMappings as $fieldName => $mapping) {
+            if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
+                $mapping['inherited'] = $parentClass->name;
+            }
+            if ( ! isset($mapping['declared'])) {
+                $mapping['declared'] = $parentClass->name;
+            }
+            $subClass->addInheritedFieldMapping($mapping);
+        }
+        foreach ($parentClass->reflFields as $name => $field) {
+            $subClass->reflFields[$name] = $field;
+        }
+    }
+
+    /**
+     * Adds inherited association mappings to the subclass mapping.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
+     */
+    private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
+    {
+        foreach ($parentClass->associationMappings as $field => $mapping) {
+            if ($parentClass->isMappedSuperclass) {
+                if ($mapping['type'] & ClassMetadata::TO_MANY && !$mapping['isOwningSide']) {
+                    throw MappingException::illegalToManyAssocationOnMappedSuperclass($parentClass->name, $field);
+                }
+                $mapping['sourceEntity'] = $subClass->name;
+            }
+
+            //$subclassMapping = $mapping;
+            if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
+                $mapping['inherited'] = $parentClass->name;
+            }
+            if ( ! isset($mapping['declared'])) {
+                $mapping['declared'] = $parentClass->name;
+            }
+            $subClass->addInheritedAssociationMapping($mapping);
+        }
+    }
+
+    /**
+     * Adds inherited named queries to the subclass mapping.
+     *
+     * @since 2.2
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
+     */
+    private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
+    {
+        foreach ($parentClass->namedQueries as $name => $query) {
+            if (!isset ($subClass->namedQueries[$name])) {
+                $subClass->addNamedQuery(array(
+                    'name'  => $query['name'],
+                    'query' => $query['query']
+                ));
+            }
+        }
+    }
+
+    /**
+     * Completes the ID generator mapping. If "auto" is specified we choose the generator
+     * most appropriate for the targeted database platform.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     */
+    private function completeIdGeneratorMapping(ClassMetadataInfo $class)
+    {
+        $idGenType = $class->generatorType;
+        if ($idGenType == ClassMetadata::GENERATOR_TYPE_AUTO) {
+            if ($this->targetPlatform->prefersSequences()) {
+                $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE);
+            } else if ($this->targetPlatform->prefersIdentityColumns()) {
+                $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_IDENTITY);
+            } else {
+                $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE);
+            }
+        }
+
+        // Create & assign an appropriate ID generator instance
+        switch ($class->generatorType) {
+            case ClassMetadata::GENERATOR_TYPE_IDENTITY:
+                // For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
+                // <table>_<column>_seq in PostgreSQL for SERIAL columns.
+                // Not pretty but necessary and the simplest solution that currently works.
+                $seqName = $this->targetPlatform instanceof Platforms\PostgreSQLPlatform ?
+                        $class->getTableName() . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
+                        null;
+                $class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
+                break;
+            case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
+                // If there is no sequence definition yet, create a default definition
+                $definition = $class->sequenceGeneratorDefinition;
+                if ( ! $definition) {
+                    $sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
+                    $definition['sequenceName'] = $this->targetPlatform->fixSchemaElementName($sequenceName);
+                    $definition['allocationSize'] = 1;
+                    $definition['initialValue'] = 1;
+                    $class->setSequenceGeneratorDefinition($definition);
+                }
+                $sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
+                    $definition['sequenceName'],
+                    $definition['allocationSize']
+                );
+                $class->setIdGenerator($sequenceGenerator);
+                break;
+            case ClassMetadata::GENERATOR_TYPE_NONE:
+                $class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
+                break;
+            case ClassMetadata::GENERATOR_TYPE_TABLE:
+                throw new ORMException("TableGenerator not yet implemented.");
+                break;
+            default:
+                throw new ORMException("Unknown generator type: " . $class->generatorType);
+        }
+    }
+
+    /**
+     * Check if this class is mapped by this EntityManager + ClassMetadata configuration
+     *
+     * @param $class
+     * @return bool
+     */
+    public function isTransient($class)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        // Check for namespace alias
+        if (strpos($class, ':') !== false) {
+            list($namespaceAlias, $simpleClassName) = explode(':', $class);
+            $class = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
+        }
+
+        return $this->driver->isTransient($class);
+    }
+
+    /**
+     * Get reflectionService.
+     *
+     * @return \Doctrine\Common\Persistence\Mapping\ReflectionService
+     */
+    public function getReflectionService()
+    {
+        if ($this->reflectionService === null) {
+            $this->reflectionService = new RuntimeReflectionService();
+        }
+        return $this->reflectionService;
+    }
+
+    /**
+     * Set reflectionService.
+     *
+     * @param reflectionService the value to set.
+     */
+    public function setReflectionService(ReflectionService $reflectionService)
+    {
+        $this->reflectionService = $reflectionService;
+    }
+
+    /**
+     * Wakeup reflection after ClassMetadata gets unserialized from cache.
+     *
+     * @param ClassMetadataInfo $class
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    protected function wakeupReflection(ClassMetadataInfo $class, ReflectionService $reflService)
+    {
+        $class->wakeupReflection($reflService);
+    }
+
+    /**
+     * Initialize Reflection after ClassMetadata was constructed.
+     *
+     * @param ClassMetadataInfo $class
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    protected function initializeReflection(ClassMetadataInfo $class, ReflectionService $reflService)
+    {
+        $class->initializeReflection($reflService);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataInfo.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataInfo.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ClassMetadataInfo.php	(revision 345)
@@ -0,0 +1,2340 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+use Doctrine\DBAL\Types\Type;
+use ReflectionClass;
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
+ * of an entity and it's associations.
+ *
+ * Once populated, ClassMetadata instances are usually cached in a serialized form.
+ *
+ * <b>IMPORTANT NOTE:</b>
+ *
+ * The fields of this class are only public for 2 reasons:
+ * 1) To allow fast READ access.
+ * 2) To drastically reduce the size of a serialized instance (private/protected members
+ *    get the whole class name, namespace inclusive, prepended to every property in
+ *    the serialized representation).
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @since 2.0
+ */
+class ClassMetadataInfo implements ClassMetadata
+{
+    /* The inheritance mapping types */
+    /**
+     * NONE means the class does not participate in an inheritance hierarchy
+     * and therefore does not need an inheritance mapping type.
+     */
+    const INHERITANCE_TYPE_NONE = 1;
+    /**
+     * JOINED means the class will be persisted according to the rules of
+     * <tt>Class Table Inheritance</tt>.
+     */
+    const INHERITANCE_TYPE_JOINED = 2;
+    /**
+     * SINGLE_TABLE means the class will be persisted according to the rules of
+     * <tt>Single Table Inheritance</tt>.
+     */
+    const INHERITANCE_TYPE_SINGLE_TABLE = 3;
+    /**
+     * TABLE_PER_CLASS means the class will be persisted according to the rules
+     * of <tt>Concrete Table Inheritance</tt>.
+     */
+    const INHERITANCE_TYPE_TABLE_PER_CLASS = 4;
+
+    /* The Id generator types. */
+    /**
+     * AUTO means the generator type will depend on what the used platform prefers.
+     * Offers full portability.
+     */
+    const GENERATOR_TYPE_AUTO = 1;
+    /**
+     * SEQUENCE means a separate sequence object will be used. Platforms that do
+     * not have native sequence support may emulate it. Full portability is currently
+     * not guaranteed.
+     */
+    const GENERATOR_TYPE_SEQUENCE = 2;
+    /**
+     * TABLE means a separate table is used for id generation.
+     * Offers full portability.
+     */
+    const GENERATOR_TYPE_TABLE = 3;
+    /**
+     * IDENTITY means an identity column is used for id generation. The database
+     * will fill in the id column on insertion. Platforms that do not support
+     * native identity columns may emulate them. Full portability is currently
+     * not guaranteed.
+     */
+    const GENERATOR_TYPE_IDENTITY = 4;
+    /**
+     * NONE means the class does not have a generated id. That means the class
+     * must have a natural, manually assigned id.
+     */
+    const GENERATOR_TYPE_NONE = 5;
+    /**
+     * DEFERRED_IMPLICIT means that changes of entities are calculated at commit-time
+     * by doing a property-by-property comparison with the original data. This will
+     * be done for all entities that are in MANAGED state at commit-time.
+     *
+     * This is the default change tracking policy.
+     */
+    const CHANGETRACKING_DEFERRED_IMPLICIT = 1;
+    /**
+     * DEFERRED_EXPLICIT means that changes of entities are calculated at commit-time
+     * by doing a property-by-property comparison with the original data. This will
+     * be done only for entities that were explicitly saved (through persist() or a cascade).
+     */
+    const CHANGETRACKING_DEFERRED_EXPLICIT = 2;
+    /**
+     * NOTIFY means that Doctrine relies on the entities sending out notifications
+     * when their properties change. Such entity classes must implement
+     * the <tt>NotifyPropertyChanged</tt> interface.
+     */
+    const CHANGETRACKING_NOTIFY = 3;
+    /**
+     * Specifies that an association is to be fetched when it is first accessed.
+     */
+    const FETCH_LAZY = 2;
+    /**
+     * Specifies that an association is to be fetched when the owner of the
+     * association is fetched.
+     */
+    const FETCH_EAGER = 3;
+    /**
+     * Specifies that an association is to be fetched lazy (on first access) and that
+     * commands such as Collection#count, Collection#slice are issued directly against
+     * the database if the collection is not yet initialized.
+     */
+    const FETCH_EXTRA_LAZY = 4;
+    /**
+     * Identifies a one-to-one association.
+     */
+    const ONE_TO_ONE = 1;
+    /**
+     * Identifies a many-to-one association.
+     */
+    const MANY_TO_ONE = 2;
+    /**
+     * Identifies a one-to-many association.
+     */
+    const ONE_TO_MANY = 4;
+    /**
+     * Identifies a many-to-many association.
+     */
+    const MANY_TO_MANY = 8;
+    /**
+     * Combined bitmask for to-one (single-valued) associations.
+     */
+    const TO_ONE = 3;
+    /**
+     * Combined bitmask for to-many (collection-valued) associations.
+     */
+    const TO_MANY = 12;
+
+    /**
+     * READ-ONLY: The name of the entity class.
+     */
+    public $name;
+
+    /**
+     * READ-ONLY: The namespace the entity class is contained in.
+     *
+     * @var string
+     * @todo Not really needed. Usage could be localized.
+     */
+    public $namespace;
+
+    /**
+     * READ-ONLY: The name of the entity class that is at the root of the mapped entity inheritance
+     * hierarchy. If the entity is not part of a mapped inheritance hierarchy this is the same
+     * as {@link $entityName}.
+     *
+     * @var string
+     */
+    public $rootEntityName;
+
+    /**
+     * The name of the custom repository class used for the entity class.
+     * (Optional).
+     *
+     * @var string
+     */
+    public $customRepositoryClassName;
+
+    /**
+     * READ-ONLY: Whether this class describes the mapping of a mapped superclass.
+     *
+     * @var boolean
+     */
+    public $isMappedSuperclass = false;
+
+    /**
+     * READ-ONLY: The names of the parent classes (ancestors).
+     *
+     * @var array
+     */
+    public $parentClasses = array();
+
+    /**
+     * READ-ONLY: The names of all subclasses (descendants).
+     *
+     * @var array
+     */
+    public $subClasses = array();
+
+    /**
+     * READ-ONLY: The named queries allowed to be called directly from Repository.
+     *
+     * @var array
+     */
+    public $namedQueries = array();
+
+    /**
+     * READ-ONLY: The field names of all fields that are part of the identifier/primary key
+     * of the mapped entity class.
+     *
+     * @var array
+     */
+    public $identifier = array();
+
+    /**
+     * READ-ONLY: The inheritance mapping type used by the class.
+     *
+     * @var integer
+     */
+    public $inheritanceType = self::INHERITANCE_TYPE_NONE;
+
+    /**
+     * READ-ONLY: The Id generator type used by the class.
+     *
+     * @var string
+     */
+    public $generatorType = self::GENERATOR_TYPE_NONE;
+
+    /**
+     * READ-ONLY: The field mappings of the class.
+     * Keys are field names and values are mapping definitions.
+     *
+     * The mapping definition array has the following values:
+     *
+     * - <b>fieldName</b> (string)
+     * The name of the field in the Entity.
+     *
+     * - <b>type</b> (string)
+     * The type name of the mapped field. Can be one of Doctrine's mapping types
+     * or a custom mapping type.
+     *
+     * - <b>columnName</b> (string, optional)
+     * The column name. Optional. Defaults to the field name.
+     *
+     * - <b>length</b> (integer, optional)
+     * The database length of the column. Optional. Default value taken from
+     * the type.
+     *
+     * - <b>id</b> (boolean, optional)
+     * Marks the field as the primary key of the entity. Multiple fields of an
+     * entity can have the id attribute, forming a composite key.
+     *
+     * - <b>nullable</b> (boolean, optional)
+     * Whether the column is nullable. Defaults to FALSE.
+     *
+     * - <b>columnDefinition</b> (string, optional, schema-only)
+     * The SQL fragment that is used when generating the DDL for the column.
+     *
+     * - <b>precision</b> (integer, optional, schema-only)
+     * The precision of a decimal column. Only valid if the column type is decimal.
+     *
+     * - <b>scale</b> (integer, optional, schema-only)
+     * The scale of a decimal column. Only valid if the column type is decimal.
+     *
+     [* - <b>'unique'] (string, optional, schema-only)</b>
+     * Whether a unique constraint should be generated for the column.
+     *
+     * @var array
+     */
+    public $fieldMappings = array();
+
+    /**
+     * READ-ONLY: An array of field names. Used to look up field names from column names.
+     * Keys are column names and values are field names.
+     * This is the reverse lookup map of $_columnNames.
+     *
+     * @var array
+     */
+    public $fieldNames = array();
+
+    /**
+     * READ-ONLY: A map of field names to column names. Keys are field names and values column names.
+     * Used to look up column names from field names.
+     * This is the reverse lookup map of $_fieldNames.
+     *
+     * @var array
+     * @todo We could get rid of this array by just using $fieldMappings[$fieldName]['columnName'].
+     */
+    public $columnNames = array();
+
+    /**
+     * READ-ONLY: The discriminator value of this class.
+     *
+     * <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
+     * where a discriminator column is used.</b>
+     *
+     * @var mixed
+     * @see discriminatorColumn
+     */
+    public $discriminatorValue;
+
+    /**
+     * READ-ONLY: The discriminator map of all mapped classes in the hierarchy.
+     *
+     * <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
+     * where a discriminator column is used.</b>
+     *
+     * @var mixed
+     * @see discriminatorColumn
+     */
+    public $discriminatorMap = array();
+
+    /**
+     * READ-ONLY: The definition of the discriminator column used in JOINED and SINGLE_TABLE
+     * inheritance mappings.
+     *
+     * @var array
+     */
+    public $discriminatorColumn;
+
+    /**
+     * READ-ONLY: The primary table definition. The definition is an array with the
+     * following entries:
+     *
+     * name => <tableName>
+     * schema => <schemaName>
+     * indexes => array
+     * uniqueConstraints => array
+     *
+     * @var array
+     */
+    public $table;
+
+    /**
+     * READ-ONLY: The registered lifecycle callbacks for entities of this class.
+     *
+     * @var array
+     */
+    public $lifecycleCallbacks = array();
+
+    /**
+     * READ-ONLY: The association mappings of this class.
+     *
+     * The mapping definition array supports the following keys:
+     *
+     * - <b>fieldName</b> (string)
+     * The name of the field in the entity the association is mapped to.
+     *
+     * - <b>targetEntity</b> (string)
+     * The class name of the target entity. If it is fully-qualified it is used as is.
+     * If it is a simple, unqualified class name the namespace is assumed to be the same
+     * as the namespace of the source entity.
+     *
+     * - <b>mappedBy</b> (string, required for bidirectional associations)
+     * The name of the field that completes the bidirectional association on the owning side.
+     * This key must be specified on the inverse side of a bidirectional association.
+     *
+     * - <b>inversedBy</b> (string, required for bidirectional associations)
+     * The name of the field that completes the bidirectional association on the inverse side.
+     * This key must be specified on the owning side of a bidirectional association.
+     *
+     * - <b>cascade</b> (array, optional)
+     * The names of persistence operations to cascade on the association. The set of possible
+     * values are: "persist", "remove", "detach", "merge", "refresh", "all" (implies all others).
+     *
+     * - <b>orderBy</b> (array, one-to-many/many-to-many only)
+     * A map of field names (of the target entity) to sorting directions (ASC/DESC).
+     * Example: array('priority' => 'desc')
+     *
+     * - <b>fetch</b> (integer, optional)
+     * The fetching strategy to use for the association, usually defaults to FETCH_LAZY.
+     * Possible values are: ClassMetadata::FETCH_EAGER, ClassMetadata::FETCH_LAZY.
+     *
+     * - <b>joinTable</b> (array, optional, many-to-many only)
+     * Specification of the join table and its join columns (foreign keys).
+     * Only valid for many-to-many mappings. Note that one-to-many associations can be mapped
+     * through a join table by simply mapping the association as many-to-many with a unique
+     * constraint on the join table.
+     *
+     * - <b>indexBy</b> (string, optional, to-many only)
+     * Specification of a field on target-entity that is used to index the collection by.
+     * This field HAS to be either the primary key or a unique column. Otherwise the collection
+     * does not contain all the entities that are actually related.
+     *
+     * A join table definition has the following structure:
+     * <pre>
+     * array(
+     *     'name' => <join table name>,
+     *      'joinColumns' => array(<join column mapping from join table to source table>),
+     *      'inverseJoinColumns' => array(<join column mapping from join table to target table>)
+     * )
+     * </pre>
+     *
+     *
+     * @var array
+     */
+    public $associationMappings = array();
+
+    /**
+     * READ-ONLY: Flag indicating whether the identifier/primary key of the class is composite.
+     *
+     * @var boolean
+     */
+    public $isIdentifierComposite = false;
+
+    /**
+     * READ-ONLY: Flag indicating wheather the identifier/primary key contains at least one foreign key association.
+     *
+     * This flag is necessary because some code blocks require special treatment of this cases.
+     *
+     * @var boolean
+     */
+    public $containsForeignIdentifier = false;
+
+    /**
+     * READ-ONLY: The ID generator used for generating IDs for this class.
+     *
+     * @var AbstractIdGenerator
+     * @todo Remove!
+     */
+    public $idGenerator;
+
+    /**
+     * READ-ONLY: The definition of the sequence generator of this class. Only used for the
+     * SEQUENCE generation strategy.
+     *
+     * The definition has the following structure:
+     * <code>
+     * array(
+     *     'sequenceName' => 'name',
+     *     'allocationSize' => 20,
+     *     'initialValue' => 1
+     * )
+     * </code>
+     *
+     * @var array
+     * @todo Merge with tableGeneratorDefinition into generic generatorDefinition
+     */
+    public $sequenceGeneratorDefinition;
+
+    /**
+     * READ-ONLY: The definition of the table generator of this class. Only used for the
+     * TABLE generation strategy.
+     *
+     * @var array
+     * @todo Merge with tableGeneratorDefinition into generic generatorDefinition
+     */
+    public $tableGeneratorDefinition;
+
+    /**
+     * READ-ONLY: The policy used for change-tracking on entities of this class.
+     *
+     * @var integer
+     */
+    public $changeTrackingPolicy = self::CHANGETRACKING_DEFERRED_IMPLICIT;
+
+    /**
+     * READ-ONLY: A flag for whether or not instances of this class are to be versioned
+     * with optimistic locking.
+     *
+     * @var boolean $isVersioned
+     */
+    public $isVersioned;
+
+    /**
+     * READ-ONLY: The name of the field which is used for versioning in optimistic locking (if any).
+     *
+     * @var mixed $versionField
+     */
+    public $versionField;
+
+    /**
+     * The ReflectionClass instance of the mapped class.
+     *
+     * @var ReflectionClass
+     */
+    public $reflClass;
+
+    /**
+     * Is this entity marked as "read-only"?
+     *
+     * That means it is never considered for change-tracking in the UnitOfWork. It is a very helpful performance
+     * optimization for entities that are immutable, either in your domain or through the relation database
+     * (coming from a view, or a history table for example).
+     *
+     * @var bool
+     */
+    public $isReadOnly = false;
+
+    /**
+     * The ReflectionProperty instances of the mapped class.
+     *
+     * @var array
+     */
+    public $reflFields = array();
+
+    /**
+     * The prototype from which new instances of the mapped class are created.
+     *
+     * @var object
+     */
+    private $_prototype;
+
+    /**
+     * Initializes a new ClassMetadata instance that will hold the object-relational mapping
+     * metadata of the class with the given name.
+     *
+     * @param string $entityName The name of the entity class the new instance is used for.
+     */
+    public function __construct($entityName)
+    {
+        $this->name = $entityName;
+        $this->rootEntityName = $entityName;
+    }
+
+    /**
+     * Gets the ReflectionPropertys of the mapped class.
+     *
+     * @return array An array of ReflectionProperty instances.
+     */
+    public function getReflectionProperties()
+    {
+        return $this->reflFields;
+    }
+
+    /**
+     * Gets a ReflectionProperty for a specific field of the mapped class.
+     *
+     * @param string $name
+     * @return ReflectionProperty
+     */
+    public function getReflectionProperty($name)
+    {
+        return $this->reflFields[$name];
+    }
+
+    /**
+     * Gets the ReflectionProperty for the single identifier field.
+     *
+     * @return ReflectionProperty
+     * @throws BadMethodCallException If the class has a composite identifier.
+     */
+    public function getSingleIdReflectionProperty()
+    {
+        if ($this->isIdentifierComposite) {
+            throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier.");
+        }
+        return $this->reflFields[$this->identifier[0]];
+    }
+
+    /**
+     * Extracts the identifier values of an entity of this class.
+     *
+     * For composite identifiers, the identifier values are returned as an array
+     * with the same order as the field order in {@link identifier}.
+     *
+     * @param object $entity
+     * @return array
+     */
+    public function getIdentifierValues($entity)
+    {
+        if ($this->isIdentifierComposite) {
+            $id = array();
+
+            foreach ($this->identifier as $idField) {
+                $value = $this->reflFields[$idField]->getValue($entity);
+
+                if ($value !== null) {
+                    $id[$idField] = $value;
+                }
+            }
+
+            return $id;
+        }
+
+        $value = $this->reflFields[$this->identifier[0]]->getValue($entity);
+
+        if ($value !== null) {
+            return array($this->identifier[0] => $value);
+        }
+
+        return array();
+    }
+
+    /**
+     * Populates the entity identifier of an entity.
+     *
+     * @param object $entity
+     * @param mixed $id
+     * @todo Rename to assignIdentifier()
+     */
+    public function setIdentifierValues($entity, array $id)
+    {
+        foreach ($id as $idField => $idValue) {
+            $this->reflFields[$idField]->setValue($entity, $idValue);
+        }
+    }
+
+    /**
+     * Sets the specified field to the specified value on the given entity.
+     *
+     * @param object $entity
+     * @param string $field
+     * @param mixed $value
+     */
+    public function setFieldValue($entity, $field, $value)
+    {
+        $this->reflFields[$field]->setValue($entity, $value);
+    }
+
+    /**
+     * Gets the specified field's value off the given entity.
+     *
+     * @param object $entity
+     * @param string $field
+     */
+    public function getFieldValue($entity, $field)
+    {
+        return $this->reflFields[$field]->getValue($entity);
+    }
+
+    /**
+     * Creates a string representation of this instance.
+     *
+     * @return string The string representation of this instance.
+     * @todo Construct meaningful string representation.
+     */
+    public function __toString()
+    {
+        return __CLASS__ . '@' . spl_object_hash($this);
+    }
+
+    /**
+     * Determines which fields get serialized.
+     *
+     * It is only serialized what is necessary for best unserialization performance.
+     * That means any metadata properties that are not set or empty or simply have
+     * their default value are NOT serialized.
+     *
+     * Parts that are also NOT serialized because they can not be properly unserialized:
+     *      - reflClass (ReflectionClass)
+     *      - reflFields (ReflectionProperty array)
+     *
+     * @return array The names of all the fields that should be serialized.
+     */
+    public function __sleep()
+    {
+        // This metadata is always serialized/cached.
+        $serialized = array(
+            'associationMappings',
+            'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName']
+            'fieldMappings',
+            'fieldNames',
+            'identifier',
+            'isIdentifierComposite', // TODO: REMOVE
+            'name',
+            'namespace', // TODO: REMOVE
+            'table',
+            'rootEntityName',
+            'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
+        );
+
+        // The rest of the metadata is only serialized if necessary.
+        if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
+            $serialized[] = 'changeTrackingPolicy';
+        }
+
+        if ($this->customRepositoryClassName) {
+            $serialized[] = 'customRepositoryClassName';
+        }
+
+        if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) {
+            $serialized[] = 'inheritanceType';
+            $serialized[] = 'discriminatorColumn';
+            $serialized[] = 'discriminatorValue';
+            $serialized[] = 'discriminatorMap';
+            $serialized[] = 'parentClasses';
+            $serialized[] = 'subClasses';
+        }
+
+        if ($this->generatorType != self::GENERATOR_TYPE_NONE) {
+            $serialized[] = 'generatorType';
+            if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) {
+                $serialized[] = 'sequenceGeneratorDefinition';
+            }
+        }
+
+        if ($this->isMappedSuperclass) {
+            $serialized[] = 'isMappedSuperclass';
+        }
+
+        if ($this->containsForeignIdentifier) {
+            $serialized[] = 'containsForeignIdentifier';
+        }
+
+        if ($this->isVersioned) {
+            $serialized[] = 'isVersioned';
+            $serialized[] = 'versionField';
+        }
+
+        if ($this->lifecycleCallbacks) {
+            $serialized[] = 'lifecycleCallbacks';
+        }
+
+        if ($this->namedQueries) {
+            $serialized[] = 'namedQueries';
+        }
+
+        if ($this->isReadOnly) {
+            $serialized[] = 'isReadOnly';
+        }
+
+        return $serialized;
+    }
+
+    /**
+     * Creates a new instance of the mapped class, without invoking the constructor.
+     *
+     * @return object
+     */
+    public function newInstance()
+    {
+        if ($this->_prototype === null) {
+            $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
+        }
+
+        return clone $this->_prototype;
+    }
+    /**
+     * Restores some state that can not be serialized/unserialized.
+     *
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    public function wakeupReflection($reflService)
+    {
+        // Restore ReflectionClass and properties
+        $this->reflClass = $reflService->getClass($this->name);
+
+        foreach ($this->fieldMappings as $field => $mapping) {
+            $this->reflFields[$field] = isset($mapping['declared'])
+                ? $reflService->getAccessibleProperty($mapping['declared'], $field)
+                : $reflService->getAccessibleProperty($this->name, $field);
+        }
+
+        foreach ($this->associationMappings as $field => $mapping) {
+            $this->reflFields[$field] = isset($mapping['declared'])
+                ? $reflService->getAccessibleProperty($mapping['declared'], $field)
+                : $reflService->getAccessibleProperty($this->name, $field);
+        }
+    }
+
+    /**
+     * Initializes a new ClassMetadata instance that will hold the object-relational mapping
+     * metadata of the class with the given name.
+     *
+     * @param string $entityName The name of the entity class the new instance is used for.
+     */
+    public function initializeReflection($reflService)
+    {
+        $this->reflClass = $reflService->getClass($this->name);
+        $this->namespace = $reflService->getClassNamespace($this->name);
+        $this->table['name'] = $reflService->getClassShortName($this->name);
+
+        if ($this->reflClass) {
+            $this->name = $this->rootEntityName = $this->reflClass->getName();
+        }
+    }
+
+    /**
+     * Validate Identifier
+     *
+     * @return void
+     */
+    public function validateIdentifier()
+    {
+        // Verify & complete identifier mapping
+        if ( ! $this->identifier && ! $this->isMappedSuperclass) {
+            throw MappingException::identifierRequired($this->name);
+        }
+
+        if ($this->usesIdGenerator() && $this->isIdentifierComposite) {
+            throw MappingException::compositeKeyAssignedIdGeneratorRequired($this->name);
+        }
+    }
+
+    /**
+     * Validate association targets actually exist.
+     *
+     * @return void
+     */
+    public function validateAssocations()
+    {
+        foreach ($this->associationMappings as $field => $mapping) {
+            if ( ! \Doctrine\Common\ClassLoader::classExists($mapping['targetEntity']) ) {
+                throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']);
+            }
+        }
+    }
+
+    /**
+     * Validate lifecycle callbacks
+     *
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    public function validateLifecycleCallbacks($reflService)
+    {
+        foreach ($this->lifecycleCallbacks as $event => $callbacks) {
+            foreach ($callbacks as $callbackFuncName) {
+                if ( ! $reflService->hasPublicMethod($this->name, $callbackFuncName)) {
+                    throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callbackFuncName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the ReflectionClass instance of the mapped class.
+     *
+     * @return ReflectionClass
+     */
+    public function getReflectionClass()
+    {
+        return $this->reflClass;
+    }
+
+    /**
+     * Sets the change tracking policy used by this class.
+     *
+     * @param integer $policy
+     */
+    public function setChangeTrackingPolicy($policy)
+    {
+        $this->changeTrackingPolicy = $policy;
+    }
+
+    /**
+     * Whether the change tracking policy of this class is "deferred explicit".
+     *
+     * @return boolean
+     */
+    public function isChangeTrackingDeferredExplicit()
+    {
+        return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_EXPLICIT;
+    }
+
+    /**
+     * Whether the change tracking policy of this class is "deferred implicit".
+     *
+     * @return boolean
+     */
+    public function isChangeTrackingDeferredImplicit()
+    {
+        return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_IMPLICIT;
+    }
+
+    /**
+     * Whether the change tracking policy of this class is "notify".
+     *
+     * @return boolean
+     */
+    public function isChangeTrackingNotify()
+    {
+        return $this->changeTrackingPolicy == self::CHANGETRACKING_NOTIFY;
+    }
+
+    /**
+     * Checks whether a field is part of the identifier/primary key field(s).
+     *
+     * @param string $fieldName  The field name
+     * @return boolean  TRUE if the field is part of the table identifier/primary key field(s),
+     *                  FALSE otherwise.
+     */
+    public function isIdentifier($fieldName)
+    {
+        if ( ! $this->isIdentifierComposite) {
+            return $fieldName === $this->identifier[0];
+        }
+        return in_array($fieldName, $this->identifier);
+    }
+
+    /**
+     * Check if the field is unique.
+     *
+     * @param string $fieldName  The field name
+     * @return boolean  TRUE if the field is unique, FALSE otherwise.
+     */
+    public function isUniqueField($fieldName)
+    {
+        $mapping = $this->getFieldMapping($fieldName);
+        if ($mapping !== false) {
+            return isset($mapping['unique']) && $mapping['unique'] == true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if the field is not null.
+     *
+     * @param string $fieldName  The field name
+     * @return boolean  TRUE if the field is not null, FALSE otherwise.
+     */
+    public function isNullable($fieldName)
+    {
+        $mapping = $this->getFieldMapping($fieldName);
+        if ($mapping !== false) {
+            return isset($mapping['nullable']) && $mapping['nullable'] == true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets a column name for a field name.
+     * If the column name for the field cannot be found, the given field name
+     * is returned.
+     *
+     * @param string $fieldName The field name.
+     * @return string  The column name.
+     */
+    public function getColumnName($fieldName)
+    {
+        return isset($this->columnNames[$fieldName]) ?
+                $this->columnNames[$fieldName] : $fieldName;
+    }
+
+    /**
+     * Gets the mapping of a (regular) field that holds some data but not a
+     * reference to another object.
+     *
+     * @param string $fieldName  The field name.
+     * @return array  The field mapping.
+     */
+    public function getFieldMapping($fieldName)
+    {
+        if ( ! isset($this->fieldMappings[$fieldName])) {
+            throw MappingException::mappingNotFound($this->name, $fieldName);
+        }
+        return $this->fieldMappings[$fieldName];
+    }
+
+    /**
+     * Gets the mapping of an association.
+     *
+     * @see ClassMetadataInfo::$associationMappings
+     * @param string $fieldName  The field name that represents the association in
+     *                           the object model.
+     * @return array The mapping.
+     */
+    public function getAssociationMapping($fieldName)
+    {
+        if ( ! isset($this->associationMappings[$fieldName])) {
+            throw MappingException::mappingNotFound($this->name, $fieldName);
+        }
+        return $this->associationMappings[$fieldName];
+    }
+
+    /**
+     * Gets all association mappings of the class.
+     *
+     * @return array
+     */
+    public function getAssociationMappings()
+    {
+        return $this->associationMappings;
+    }
+
+    /**
+     * Gets the field name for a column name.
+     * If no field name can be found the column name is returned.
+     *
+     * @param string $columnName    column name
+     * @return string               column alias
+     */
+    public function getFieldName($columnName)
+    {
+        return isset($this->fieldNames[$columnName]) ?
+                $this->fieldNames[$columnName] : $columnName;
+    }
+
+    /**
+     * Gets the named query.
+     *
+     * @see ClassMetadataInfo::$namedQueries
+     * @throws MappingException
+     * @param string $queryName The query name
+     * @return string
+     */
+    public function getNamedQuery($queryName)
+    {
+        if ( ! isset($this->namedQueries[$queryName])) {
+            throw MappingException::queryNotFound($this->name, $queryName);
+        }
+        return $this->namedQueries[$queryName]['dql'];
+    }
+
+    /**
+     * Gets all named queries of the class.
+     *
+     * @return array
+     */
+    public function getNamedQueries()
+    {
+        return $this->namedQueries;
+    }
+
+    /**
+     * Validates & completes the given field mapping.
+     *
+     * @param array $mapping  The field mapping to validated & complete.
+     * @return array  The validated and completed field mapping.
+     */
+    protected function _validateAndCompleteFieldMapping(array &$mapping)
+    {
+        // Check mandatory fields
+        if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) {
+            throw MappingException::missingFieldName($this->name);
+        }
+        if ( ! isset($mapping['type'])) {
+            // Default to string
+            $mapping['type'] = 'string';
+        }
+
+        // Complete fieldName and columnName mapping
+        if ( ! isset($mapping['columnName'])) {
+            $mapping['columnName'] = $mapping['fieldName'];
+        } else {
+            if ($mapping['columnName'][0] == '`') {
+                $mapping['columnName'] = trim($mapping['columnName'], '`');
+                $mapping['quoted'] = true;
+            }
+        }
+
+        $this->columnNames[$mapping['fieldName']] = $mapping['columnName'];
+        if (isset($this->fieldNames[$mapping['columnName']]) || ($this->discriminatorColumn != null && $this->discriminatorColumn['name'] == $mapping['columnName'])) {
+            throw MappingException::duplicateColumnName($this->name, $mapping['columnName']);
+        }
+
+        $this->fieldNames[$mapping['columnName']] = $mapping['fieldName'];
+
+        // Complete id mapping
+        if (isset($mapping['id']) && $mapping['id'] === true) {
+            if ($this->versionField == $mapping['fieldName']) {
+                throw MappingException::cannotVersionIdField($this->name, $mapping['fieldName']);
+            }
+
+            if ( ! in_array($mapping['fieldName'], $this->identifier)) {
+                $this->identifier[] = $mapping['fieldName'];
+            }
+            // Check for composite key
+            if ( ! $this->isIdentifierComposite && count($this->identifier) > 1) {
+                $this->isIdentifierComposite = true;
+            }
+        }
+
+        if (Type::hasType($mapping['type']) && Type::getType($mapping['type'])->canRequireSQLConversion()) {
+            if (isset($mapping['id']) && $mapping['id'] === true) {
+                 throw MappingException::sqlConversionNotAllowedForIdentifiers($this->name, $mapping['fieldName'], $mapping['type']);
+            }
+
+            $mapping['requireSQLConversion'] = true;
+        }
+    }
+
+    /**
+     * Validates & completes the basic mapping information that is common to all
+     * association mappings (one-to-one, many-ot-one, one-to-many, many-to-many).
+     *
+     * @param array $mapping The mapping.
+     * @return array The updated mapping.
+     * @throws MappingException If something is wrong with the mapping.
+     */
+    protected function _validateAndCompleteAssociationMapping(array $mapping)
+    {
+        if ( ! isset($mapping['mappedBy'])) {
+            $mapping['mappedBy'] = null;
+        }
+        if ( ! isset($mapping['inversedBy'])) {
+            $mapping['inversedBy'] = null;
+        }
+        $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
+
+        // unset optional indexBy attribute if its empty
+        if (!isset($mapping['indexBy']) || !$mapping['indexBy']) {
+            unset($mapping['indexBy']);
+        }
+
+        // If targetEntity is unqualified, assume it is in the same namespace as
+        // the sourceEntity.
+        $mapping['sourceEntity'] = $this->name;
+
+        if (isset($mapping['targetEntity'])) {
+            if (strlen($this->namespace) > 0 && strpos($mapping['targetEntity'], '\\') === false) {
+                $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
+            }
+
+            $mapping['targetEntity'] = ltrim($mapping['targetEntity'], '\\');
+        }
+
+        if ( ($mapping['type'] & self::MANY_TO_ONE) > 0 &&
+                isset($mapping['orphanRemoval']) &&
+                $mapping['orphanRemoval'] == true) {
+
+            throw MappingException::illegalOrphanRemoval($this->name, $mapping['fieldName']);
+        }
+
+        // Complete id mapping
+        if (isset($mapping['id']) && $mapping['id'] === true) {
+            if (isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'] == true) {
+                throw MappingException::illegalOrphanRemovalOnIdentifierAssociation($this->name, $mapping['fieldName']);
+            }
+
+            if ( ! in_array($mapping['fieldName'], $this->identifier)) {
+                if (count($mapping['joinColumns']) >= 2) {
+                    throw MappingException::cannotMapCompositePrimaryKeyEntitiesAsForeignId(
+                        $mapping['targetEntity'], $this->name, $mapping['fieldName']
+                    );
+                }
+
+                $this->identifier[] = $mapping['fieldName'];
+                $this->containsForeignIdentifier = true;
+            }
+            // Check for composite key
+            if ( ! $this->isIdentifierComposite && count($this->identifier) > 1) {
+                $this->isIdentifierComposite = true;
+            }
+        }
+
+        // Mandatory attributes for both sides
+        // Mandatory: fieldName, targetEntity
+        if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) {
+            throw MappingException::missingFieldName($this->name);
+        }
+        if ( ! isset($mapping['targetEntity'])) {
+            throw MappingException::missingTargetEntity($mapping['fieldName']);
+        }
+
+        // Mandatory and optional attributes for either side
+        if ( ! $mapping['mappedBy']) {
+            if (isset($mapping['joinTable']) && $mapping['joinTable']) {
+                if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] == '`') {
+                    $mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`');
+                    $mapping['joinTable']['quoted'] = true;
+                }
+            }
+        } else {
+            $mapping['isOwningSide'] = false;
+        }
+
+        if (isset($mapping['id']) && $mapping['id'] === true && $mapping['type'] & self::TO_MANY) {
+            throw MappingException::illegalToManyIdentifierAssoaction($this->name, $mapping['fieldName']);
+        }
+
+        // Fetch mode. Default fetch mode to LAZY, if not set.
+        if ( ! isset($mapping['fetch'])) {
+            $mapping['fetch'] = self::FETCH_LAZY;
+        }
+
+        // Cascades
+        $cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : array();
+
+        if (in_array('all', $cascades)) {
+            $cascades = array('remove', 'persist', 'refresh', 'merge', 'detach');
+        }
+
+        $mapping['cascade'] = $cascades;
+        $mapping['isCascadeRemove'] = in_array('remove',  $cascades);
+        $mapping['isCascadePersist'] = in_array('persist',  $cascades);
+        $mapping['isCascadeRefresh'] = in_array('refresh',  $cascades);
+        $mapping['isCascadeMerge'] = in_array('merge',  $cascades);
+        $mapping['isCascadeDetach'] = in_array('detach',  $cascades);
+
+        return $mapping;
+    }
+
+    /**
+     * Validates & completes a one-to-one association mapping.
+     *
+     * @param array $mapping  The mapping to validate & complete.
+     * @return array The validated & completed mapping.
+     * @override
+     */
+    protected function _validateAndCompleteOneToOneMapping(array $mapping)
+    {
+        $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
+
+        if (isset($mapping['joinColumns']) && $mapping['joinColumns']) {
+            $mapping['isOwningSide'] = true;
+        }
+
+        if ($mapping['isOwningSide']) {
+            if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) {
+                // Apply default join column
+                $mapping['joinColumns'] = array(array(
+                    'name' => $mapping['fieldName'] . '_id',
+                    'referencedColumnName' => 'id'
+                ));
+            }
+
+            $uniqueContraintColumns = array();
+            foreach ($mapping['joinColumns'] as $key => &$joinColumn) {
+                if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
+                    if (count($mapping['joinColumns']) == 1) {
+                        if (! isset($mapping['id']) || ! $mapping['id']) {
+                            $joinColumn['unique'] = true;
+                        }
+                    } else {
+                        $uniqueContraintColumns[] = $joinColumn['name'];
+                    }
+                }
+                if (empty($joinColumn['name'])) {
+                    $joinColumn['name'] = $mapping['fieldName'] . '_id';
+                }
+                if (empty($joinColumn['referencedColumnName'])) {
+                    $joinColumn['referencedColumnName'] = 'id';
+                }
+                $mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
+                $mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName'])
+                        ? $joinColumn['fieldName'] : $joinColumn['name'];
+            }
+
+            if ($uniqueContraintColumns) {
+                if (!$this->table) {
+                    throw new \RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship.");
+                }
+                $this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array(
+                    'columns' => $uniqueContraintColumns
+                );
+            }
+
+            $mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']);
+        }
+
+        $mapping['orphanRemoval']   = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
+        $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
+
+        if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) {
+            throw MappingException::illegalInverseIdentifierAssocation($this->name, $mapping['fieldName']);
+        }
+
+        return $mapping;
+    }
+
+    /**
+     * Validates and completes the mapping.
+     *
+     * @param array $mapping The mapping to validate and complete.
+     * @return array The validated and completed mapping.
+     * @override
+     */
+    protected function _validateAndCompleteOneToManyMapping(array $mapping)
+    {
+        $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
+
+        // OneToMany-side MUST be inverse (must have mappedBy)
+        if ( ! isset($mapping['mappedBy'])) {
+            throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
+        }
+
+        $mapping['orphanRemoval']   = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
+        $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
+
+        if (isset($mapping['orderBy'])) {
+            if ( ! is_array($mapping['orderBy'])) {
+                throw new \InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy']));
+            }
+        }
+
+        return $mapping;
+    }
+
+    protected function _validateAndCompleteManyToManyMapping(array $mapping)
+    {
+        $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
+        if ($mapping['isOwningSide']) {
+            if (strpos($mapping['sourceEntity'], '\\') !== false) {
+                $sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1));
+            } else {
+                $sourceShortName = strtolower($mapping['sourceEntity']);
+            }
+            if (strpos($mapping['targetEntity'], '\\') !== false) {
+                $targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1));
+            } else {
+                $targetShortName = strtolower($mapping['targetEntity']);
+            }
+
+            // owning side MUST have a join table
+            if ( ! isset($mapping['joinTable']['name'])) {
+                $mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName;
+            }
+            if ( ! isset($mapping['joinTable']['joinColumns'])) {
+                $mapping['joinTable']['joinColumns'] = array(array(
+                        'name' => $sourceShortName . '_id',
+                        'referencedColumnName' => 'id',
+                        'onDelete' => 'CASCADE'));
+            }
+            if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
+                $mapping['joinTable']['inverseJoinColumns'] = array(array(
+                        'name' => $targetShortName . '_id',
+                        'referencedColumnName' => 'id',
+                        'onDelete' => 'CASCADE'));
+            }
+
+            foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
+                if (empty($joinColumn['name'])) {
+                    $joinColumn['name'] = $sourceShortName . '_id';
+                }
+                if (empty($joinColumn['referencedColumnName'])) {
+                    $joinColumn['referencedColumnName'] = 'id';
+                }
+                if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
+                    $mapping['isOnDeleteCascade'] = true;
+                }
+                $mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
+                $mapping['joinTableColumns'][] = $joinColumn['name'];
+            }
+
+            foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) {
+                if (empty($inverseJoinColumn['name'])) {
+                    $inverseJoinColumn['name'] = $targetShortName . '_id';
+                }
+                if (empty($inverseJoinColumn['referencedColumnName'])) {
+                    $inverseJoinColumn['referencedColumnName'] = 'id';
+                }
+                if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
+                    $mapping['isOnDeleteCascade'] = true;
+                }
+                $mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
+                $mapping['joinTableColumns'][] = $inverseJoinColumn['name'];
+            }
+        }
+
+        $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
+
+        if (isset($mapping['orderBy'])) {
+            if ( ! is_array($mapping['orderBy'])) {
+                throw new \InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy']));
+            }
+        }
+
+        return $mapping;
+    }
+
+    /**
+     * Gets the identifier (primary key) field names of the class.
+     *
+     * @return mixed
+     */
+    public function getIdentifierFieldNames()
+    {
+        return $this->identifier;
+    }
+
+    /**
+     * Gets the name of the single id field. Note that this only works on
+     * entity classes that have a single-field pk.
+     *
+     * @return string
+     * @throws MappingException If the class has a composite primary key.
+     */
+    public function getSingleIdentifierFieldName()
+    {
+        if ($this->isIdentifierComposite) {
+            throw MappingException::singleIdNotAllowedOnCompositePrimaryKey($this->name);
+        }
+        return $this->identifier[0];
+    }
+
+    /**
+     * Gets the column name of the single id column. Note that this only works on
+     * entity classes that have a single-field pk.
+     *
+     * @return string
+     * @throws MappingException If the class has a composite primary key.
+     */
+    public function getSingleIdentifierColumnName()
+    {
+        return $this->getColumnName($this->getSingleIdentifierFieldName());
+    }
+
+    /**
+     * INTERNAL:
+     * Sets the mapped identifier/primary key fields of this class.
+     * Mainly used by the ClassMetadataFactory to assign inherited identifiers.
+     *
+     * @param array $identifier
+     */
+    public function setIdentifier(array $identifier)
+    {
+        $this->identifier = $identifier;
+        $this->isIdentifierComposite = (count($this->identifier) > 1);
+    }
+
+    /**
+     * Gets the mapped identifier field of this class.
+     *
+     * @return string $identifier
+     */
+    public function getIdentifier()
+    {
+        return $this->identifier;
+    }
+
+    /**
+     * Checks whether the class has a (mapped) field with a certain name.
+     *
+     * @return boolean
+     */
+    public function hasField($fieldName)
+    {
+        return isset($this->fieldMappings[$fieldName]);
+    }
+
+    /**
+     * Gets an array containing all the column names.
+     *
+     * @return array
+     */
+    public function getColumnNames(array $fieldNames = null)
+    {
+        if ($fieldNames === null) {
+            return array_keys($this->fieldNames);
+        } else {
+            $columnNames = array();
+            foreach ($fieldNames as $fieldName) {
+                $columnNames[] = $this->getColumnName($fieldName);
+            }
+            return $columnNames;
+        }
+    }
+
+    /**
+     * Returns an array with all the identifier column names.
+     *
+     * @return array
+     */
+    public function getIdentifierColumnNames()
+    {
+        $columnNames = array();
+
+        foreach ($this->identifier as $idProperty) {
+            if (isset($this->fieldMappings[$idProperty])) {
+                $columnNames[] = $this->fieldMappings[$idProperty]['columnName'];
+
+                continue;
+            }
+
+            // Association defined as Id field
+            $joinColumns      = $this->associationMappings[$idProperty]['joinColumns'];
+            $assocColumnNames = array_map(function ($joinColumn) { return $joinColumn['name']; }, $joinColumns);
+
+            $columnNames = array_merge($columnNames, $assocColumnNames);
+        }
+
+        return $columnNames;
+    }
+
+    /**
+     * Sets the type of Id generator to use for the mapped class.
+     */
+    public function setIdGeneratorType($generatorType)
+    {
+        $this->generatorType = $generatorType;
+    }
+
+    /**
+     * Checks whether the mapped class uses an Id generator.
+     *
+     * @return boolean TRUE if the mapped class uses an Id generator, FALSE otherwise.
+     */
+    public function usesIdGenerator()
+    {
+        return $this->generatorType != self::GENERATOR_TYPE_NONE;
+    }
+
+    /**
+     * @return boolean
+     */
+    public function isInheritanceTypeNone()
+    {
+        return $this->inheritanceType == self::INHERITANCE_TYPE_NONE;
+    }
+
+    /**
+     * Checks whether the mapped class uses the JOINED inheritance mapping strategy.
+     *
+     * @return boolean TRUE if the class participates in a JOINED inheritance mapping,
+     *                 FALSE otherwise.
+     */
+    public function isInheritanceTypeJoined()
+    {
+        return $this->inheritanceType == self::INHERITANCE_TYPE_JOINED;
+    }
+
+    /**
+     * Checks whether the mapped class uses the SINGLE_TABLE inheritance mapping strategy.
+     *
+     * @return boolean TRUE if the class participates in a SINGLE_TABLE inheritance mapping,
+     *                 FALSE otherwise.
+     */
+    public function isInheritanceTypeSingleTable()
+    {
+        return $this->inheritanceType == self::INHERITANCE_TYPE_SINGLE_TABLE;
+    }
+
+    /**
+     * Checks whether the mapped class uses the TABLE_PER_CLASS inheritance mapping strategy.
+     *
+     * @return boolean TRUE if the class participates in a TABLE_PER_CLASS inheritance mapping,
+     *                 FALSE otherwise.
+     */
+    public function isInheritanceTypeTablePerClass()
+    {
+        return $this->inheritanceType == self::INHERITANCE_TYPE_TABLE_PER_CLASS;
+    }
+
+    /**
+     * Checks whether the class uses an identity column for the Id generation.
+     *
+     * @return boolean TRUE if the class uses the IDENTITY generator, FALSE otherwise.
+     */
+    public function isIdGeneratorIdentity()
+    {
+        return $this->generatorType == self::GENERATOR_TYPE_IDENTITY;
+    }
+
+    /**
+     * Checks whether the class uses a sequence for id generation.
+     *
+     * @return boolean TRUE if the class uses the SEQUENCE generator, FALSE otherwise.
+     */
+    public function isIdGeneratorSequence()
+    {
+        return $this->generatorType == self::GENERATOR_TYPE_SEQUENCE;
+    }
+
+    /**
+     * Checks whether the class uses a table for id generation.
+     *
+     * @return boolean  TRUE if the class uses the TABLE generator, FALSE otherwise.
+     */
+    public function isIdGeneratorTable()
+    {
+        $this->generatorType == self::GENERATOR_TYPE_TABLE;
+    }
+
+    /**
+     * Checks whether the class has a natural identifier/pk (which means it does
+     * not use any Id generator.
+     *
+     * @return boolean
+     */
+    public function isIdentifierNatural()
+    {
+        return $this->generatorType == self::GENERATOR_TYPE_NONE;
+    }
+
+    /**
+     * Gets the type of a field.
+     *
+     * @param string $fieldName
+     * @return \Doctrine\DBAL\Types\Type
+     */
+    public function getTypeOfField($fieldName)
+    {
+        return isset($this->fieldMappings[$fieldName]) ?
+                $this->fieldMappings[$fieldName]['type'] : null;
+    }
+
+    /**
+     * Gets the type of a column.
+     *
+     * @return \Doctrine\DBAL\Types\Type
+     */
+    public function getTypeOfColumn($columnName)
+    {
+        return $this->getTypeOfField($this->getFieldName($columnName));
+    }
+
+    /**
+     * Gets the name of the primary table.
+     *
+     * @return string
+     */
+    public function getTableName()
+    {
+        return $this->table['name'];
+    }
+
+    /**
+     * Gets the table name to use for temporary identifier tables of this class.
+     *
+     * @return string
+     */
+    public function getTemporaryIdTableName()
+    {
+        // replace dots with underscores because PostgreSQL creates temporary tables in a special schema
+        return str_replace('.', '_', $this->getTableName() . '_id_tmp');
+    }
+
+    /**
+     * Sets the mapped subclasses of this class.
+     *
+     * @param array $subclasses The names of all mapped subclasses.
+     */
+    public function setSubclasses(array $subclasses)
+    {
+        foreach ($subclasses as $subclass) {
+            if (strpos($subclass, '\\') === false && strlen($this->namespace)) {
+                $this->subClasses[] = $this->namespace . '\\' . $subclass;
+            } else {
+                $this->subClasses[] = $subclass;
+            }
+        }
+    }
+
+    /**
+     * Sets the parent class names.
+     * Assumes that the class names in the passed array are in the order:
+     * directParent -> directParentParent -> directParentParentParent ... -> root.
+     */
+    public function setParentClasses(array $classNames)
+    {
+        $this->parentClasses = $classNames;
+        if (count($classNames) > 0) {
+            $this->rootEntityName = array_pop($classNames);
+        }
+    }
+
+    /**
+     * Sets the inheritance type used by the class and it's subclasses.
+     *
+     * @param integer $type
+     */
+    public function setInheritanceType($type)
+    {
+        if ( ! $this->_isInheritanceType($type)) {
+            throw MappingException::invalidInheritanceType($this->name, $type);
+        }
+        $this->inheritanceType = $type;
+    }
+
+    /**
+     * Checks whether a mapped field is inherited from an entity superclass.
+     *
+     * @return boolean TRUE if the field is inherited, FALSE otherwise.
+     */
+    public function isInheritedField($fieldName)
+    {
+        return isset($this->fieldMappings[$fieldName]['inherited']);
+    }
+
+    /**
+     * Checks whether a mapped association field is inherited from a superclass.
+     *
+     * @param string $fieldName
+     * @return boolean TRUE if the field is inherited, FALSE otherwise.
+     */
+    public function isInheritedAssociation($fieldName)
+    {
+        return isset($this->associationMappings[$fieldName]['inherited']);
+    }
+
+    /**
+     * Sets the name of the primary table the class is mapped to.
+     *
+     * @param string $tableName The table name.
+     * @deprecated Use {@link setPrimaryTable}.
+     */
+    public function setTableName($tableName)
+    {
+        $this->table['name'] = $tableName;
+    }
+
+    /**
+     * Sets the primary table definition. The provided array supports the
+     * following structure:
+     *
+     * name => <tableName> (optional, defaults to class name)
+     * indexes => array of indexes (optional)
+     * uniqueConstraints => array of constraints (optional)
+     *
+     * If a key is omitted, the current value is kept.
+     *
+     * @param array $table The table description.
+     */
+    public function setPrimaryTable(array $table)
+    {
+        if (isset($table['name'])) {
+            if ($table['name'][0] == '`') {
+                $this->table['name'] = str_replace("`", "", $table['name']);
+                $this->table['quoted'] = true;
+            } else {
+                $this->table['name'] = $table['name'];
+            }
+        }
+
+        if (isset($table['indexes'])) {
+            $this->table['indexes'] = $table['indexes'];
+        }
+
+        if (isset($table['uniqueConstraints'])) {
+            $this->table['uniqueConstraints'] = $table['uniqueConstraints'];
+        }
+    }
+
+    /**
+     * Checks whether the given type identifies an inheritance type.
+     *
+     * @param integer $type
+     * @return boolean TRUE if the given type identifies an inheritance type, FALSe otherwise.
+     */
+    private function _isInheritanceType($type)
+    {
+        return $type == self::INHERITANCE_TYPE_NONE ||
+                $type == self::INHERITANCE_TYPE_SINGLE_TABLE ||
+                $type == self::INHERITANCE_TYPE_JOINED ||
+                $type == self::INHERITANCE_TYPE_TABLE_PER_CLASS;
+    }
+
+    /**
+     * Adds a mapped field to the class.
+     *
+     * @param array $mapping The field mapping.
+     */
+    public function mapField(array $mapping)
+    {
+        $this->_validateAndCompleteFieldMapping($mapping);
+        if (isset($this->fieldMappings[$mapping['fieldName']]) || isset($this->associationMappings[$mapping['fieldName']])) {
+            throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']);
+        }
+        $this->fieldMappings[$mapping['fieldName']] = $mapping;
+    }
+
+    /**
+     * INTERNAL:
+     * Adds an association mapping without completing/validating it.
+     * This is mainly used to add inherited association mappings to derived classes.
+     *
+     * @param array $mapping
+     */
+    public function addInheritedAssociationMapping(array $mapping/*, $owningClassName = null*/)
+    {
+        if (isset($this->associationMappings[$mapping['fieldName']])) {
+            throw MappingException::duplicateAssociationMapping($this->name, $mapping['fieldName']);
+        }
+        $this->associationMappings[$mapping['fieldName']] = $mapping;
+    }
+
+    /**
+     * INTERNAL:
+     * Adds a field mapping without completing/validating it.
+     * This is mainly used to add inherited field mappings to derived classes.
+     *
+     * @param array $mapping
+     */
+    public function addInheritedFieldMapping(array $fieldMapping)
+    {
+        $this->fieldMappings[$fieldMapping['fieldName']] = $fieldMapping;
+        $this->columnNames[$fieldMapping['fieldName']] = $fieldMapping['columnName'];
+        $this->fieldNames[$fieldMapping['columnName']] = $fieldMapping['fieldName'];
+    }
+
+    /**
+     * INTERNAL:
+     * Adds a named query to this class.
+     *
+     * @throws MappingException
+     * @param array $queryMapping
+     */
+    public function addNamedQuery(array $queryMapping)
+    {
+        if (isset($this->namedQueries[$queryMapping['name']])) {
+            throw MappingException::duplicateQueryMapping($this->name, $queryMapping['name']);
+        }
+
+        $name   = $queryMapping['name'];
+        $query  = $queryMapping['query'];
+        $dql    = str_replace('__CLASS__', $this->name, $query);
+        $this->namedQueries[$name] = array(
+            'name'  => $name,
+            'query' => $query,
+            'dql'   => $dql
+        );
+    }
+
+    /**
+     * Adds a one-to-one mapping.
+     *
+     * @param array $mapping The mapping.
+     */
+    public function mapOneToOne(array $mapping)
+    {
+        $mapping['type'] = self::ONE_TO_ONE;
+        $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
+        $this->_storeAssociationMapping($mapping);
+    }
+
+    /**
+     * Adds a one-to-many mapping.
+     *
+     * @param array $mapping The mapping.
+     */
+    public function mapOneToMany(array $mapping)
+    {
+        $mapping['type'] = self::ONE_TO_MANY;
+        $mapping = $this->_validateAndCompleteOneToManyMapping($mapping);
+        $this->_storeAssociationMapping($mapping);
+    }
+
+    /**
+     * Adds a many-to-one mapping.
+     *
+     * @param array $mapping The mapping.
+     */
+    public function mapManyToOne(array $mapping)
+    {
+        $mapping['type'] = self::MANY_TO_ONE;
+        // A many-to-one mapping is essentially a one-one backreference
+        $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
+        $this->_storeAssociationMapping($mapping);
+    }
+
+    /**
+     * Adds a many-to-many mapping.
+     *
+     * @param array $mapping The mapping.
+     */
+    public function mapManyToMany(array $mapping)
+    {
+        $mapping['type'] = self::MANY_TO_MANY;
+        $mapping = $this->_validateAndCompleteManyToManyMapping($mapping);
+        $this->_storeAssociationMapping($mapping);
+    }
+
+    /**
+     * Stores the association mapping.
+     *
+     * @param array $assocMapping
+     */
+    protected function _storeAssociationMapping(array $assocMapping)
+    {
+        $sourceFieldName = $assocMapping['fieldName'];
+
+        if (isset($this->fieldMappings[$sourceFieldName]) || isset($this->associationMappings[$sourceFieldName])) {
+            throw MappingException::duplicateFieldMapping($this->name, $sourceFieldName);
+        }
+
+        $this->associationMappings[$sourceFieldName] = $assocMapping;
+    }
+
+    /**
+     * Registers a custom repository class for the entity class.
+     *
+     * @param string $mapperClassName  The class name of the custom mapper.
+     */
+    public function setCustomRepositoryClass($repositoryClassName)
+    {
+        if ($repositoryClassName !== null && strpos($repositoryClassName, '\\') === false
+                && strlen($this->namespace) > 0) {
+            $repositoryClassName = $this->namespace . '\\' . $repositoryClassName;
+        }
+        $this->customRepositoryClassName = $repositoryClassName;
+    }
+
+    /**
+     * Dispatches the lifecycle event of the given entity to the registered
+     * lifecycle callbacks and lifecycle listeners.
+     *
+     * @param string $event The lifecycle event.
+     * @param Entity $entity The Entity on which the event occured.
+     */
+    public function invokeLifecycleCallbacks($lifecycleEvent, $entity)
+    {
+        foreach ($this->lifecycleCallbacks[$lifecycleEvent] as $callback) {
+            $entity->$callback();
+        }
+    }
+
+    /**
+     * Whether the class has any attached lifecycle listeners or callbacks for a lifecycle event.
+     *
+     * @param string $lifecycleEvent
+     * @return boolean
+     */
+    public function hasLifecycleCallbacks($lifecycleEvent)
+    {
+        return isset($this->lifecycleCallbacks[$lifecycleEvent]);
+    }
+
+    /**
+     * Gets the registered lifecycle callbacks for an event.
+     *
+     * @param string $event
+     * @return array
+     */
+    public function getLifecycleCallbacks($event)
+    {
+        return isset($this->lifecycleCallbacks[$event]) ? $this->lifecycleCallbacks[$event] : array();
+    }
+
+    /**
+     * Adds a lifecycle callback for entities of this class.
+     *
+     * @param string $callback
+     * @param string $event
+     */
+    public function addLifecycleCallback($callback, $event)
+    {
+        $this->lifecycleCallbacks[$event][] = $callback;
+    }
+
+    /**
+     * Sets the lifecycle callbacks for entities of this class.
+     * Any previously registered callbacks are overwritten.
+     *
+     * @param array $callbacks
+     */
+    public function setLifecycleCallbacks(array $callbacks)
+    {
+        $this->lifecycleCallbacks = $callbacks;
+    }
+
+    /**
+     * Sets the discriminator column definition.
+     *
+     * @param array $columnDef
+     * @see getDiscriminatorColumn()
+     */
+    public function setDiscriminatorColumn($columnDef)
+    {
+        if ($columnDef !== null) {
+            if (isset($this->fieldNames[$columnDef['name']])) {
+                throw MappingException::duplicateColumnName($this->name, $columnDef['name']);
+            }
+
+            if ( ! isset($columnDef['name'])) {
+                throw MappingException::nameIsMandatoryForDiscriminatorColumns($this->name, $columnDef);
+            }
+            if ( ! isset($columnDef['fieldName'])) {
+                $columnDef['fieldName'] = $columnDef['name'];
+            }
+            if ( ! isset($columnDef['type'])) {
+                $columnDef['type'] = "string";
+            }
+            if (in_array($columnDef['type'], array("boolean", "array", "object", "datetime", "time", "date"))) {
+                throw MappingException::invalidDiscriminatorColumnType($this->name, $columnDef['type']);
+            }
+
+            $this->discriminatorColumn = $columnDef;
+        }
+    }
+
+    /**
+     * Sets the discriminator values used by this class.
+     * Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
+     *
+     * @param array $map
+     */
+    public function setDiscriminatorMap(array $map)
+    {
+        foreach ($map as $value => $className) {
+            $this->addDiscriminatorMapClass($value, $className);
+        }
+    }
+
+    /**
+     * Add one entry of the discriminator map with a new class and corresponding name.
+     *
+     * @param string $name
+     * @param string $className
+     */
+    public function addDiscriminatorMapClass($name, $className)
+    {
+        if (strlen($this->namespace) > 0 && strpos($className, '\\') === false) {
+            $className = $this->namespace . '\\' . $className;
+        }
+
+        $className = ltrim($className, '\\');
+        $this->discriminatorMap[$name] = $className;
+
+        if ($this->name == $className) {
+            $this->discriminatorValue = $name;
+        } else {
+            if ( ! class_exists($className)) {
+                throw MappingException::invalidClassInDiscriminatorMap($className, $this->name);
+            }
+            if (is_subclass_of($className, $this->name) && ! in_array($className, $this->subClasses)) {
+                $this->subClasses[] = $className;
+            }
+        }
+    }
+
+    /**
+     * Checks whether the class has a named query with the given query name.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    public function hasNamedQuery($queryName)
+    {
+        return isset($this->namedQueries[$queryName]);
+    }
+
+    /**
+     * Checks whether the class has a mapped association with the given field name.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    public function hasAssociation($fieldName)
+    {
+        return isset($this->associationMappings[$fieldName]);
+    }
+
+    /**
+     * Checks whether the class has a mapped association for the specified field
+     * and if yes, checks whether it is a single-valued association (to-one).
+     *
+     * @param string $fieldName
+     * @return boolean TRUE if the association exists and is single-valued, FALSE otherwise.
+     */
+    public function isSingleValuedAssociation($fieldName)
+    {
+        return isset($this->associationMappings[$fieldName]) &&
+                ($this->associationMappings[$fieldName]['type'] & self::TO_ONE);
+    }
+
+    /**
+     * Checks whether the class has a mapped association for the specified field
+     * and if yes, checks whether it is a collection-valued association (to-many).
+     *
+     * @param string $fieldName
+     * @return boolean TRUE if the association exists and is collection-valued, FALSE otherwise.
+     */
+    public function isCollectionValuedAssociation($fieldName)
+    {
+        return isset($this->associationMappings[$fieldName]) &&
+                ! ($this->associationMappings[$fieldName]['type'] & self::TO_ONE);
+    }
+
+    /**
+     * Is this an association that only has a single join column?
+     *
+     * @param  string $fieldName
+     * @return bool
+     */
+    public function isAssociationWithSingleJoinColumn($fieldName)
+    {
+        return (
+            isset($this->associationMappings[$fieldName]) &&
+            isset($this->associationMappings[$fieldName]['joinColumns'][0]) &&
+            !isset($this->associationMappings[$fieldName]['joinColumns'][1])
+        );
+    }
+
+    /**
+     * Return the single association join column (if any).
+     *
+     * @param string $fieldName
+     * @return string
+     */
+    public function getSingleAssociationJoinColumnName($fieldName)
+    {
+        if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
+            throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
+        }
+        return $this->associationMappings[$fieldName]['joinColumns'][0]['name'];
+    }
+
+    /**
+     * Return the single association referenced join column name (if any).
+     *
+     * @param string $fieldName
+     * @return string
+     */
+    public function getSingleAssociationReferencedJoinColumnName($fieldName)
+    {
+        if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
+            throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
+        }
+        return $this->associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName'];
+    }
+
+    /**
+     * Used to retrieve a fieldname for either field or association from a given column,
+     *
+     * This method is used in foreign-key as primary-key contexts.
+     *
+     * @param  string $columnName
+     * @return string
+     */
+    public function getFieldForColumn($columnName)
+    {
+        if (isset($this->fieldNames[$columnName])) {
+            return $this->fieldNames[$columnName];
+        } else {
+            foreach ($this->associationMappings AS $assocName => $mapping) {
+                if ($this->isAssociationWithSingleJoinColumn($assocName) &&
+                    $this->associationMappings[$assocName]['joinColumns'][0]['name'] == $columnName) {
+
+                    return $assocName;
+                }
+            }
+
+            throw MappingException::noFieldNameFoundForColumn($this->name, $columnName);
+        }
+    }
+
+    /**
+     * Sets the ID generator used to generate IDs for instances of this class.
+     *
+     * @param AbstractIdGenerator $generator
+     */
+    public function setIdGenerator($generator)
+    {
+        $this->idGenerator = $generator;
+    }
+
+    /**
+     * Sets the definition of the sequence ID generator for this class.
+     *
+     * The definition must have the following structure:
+     * <code>
+     * array(
+     *     'sequenceName' => 'name',
+     *     'allocationSize' => 20,
+     *     'initialValue' => 1
+     * )
+     * </code>
+     *
+     * @param array $definition
+     */
+    public function setSequenceGeneratorDefinition(array $definition)
+    {
+        $this->sequenceGeneratorDefinition = $definition;
+    }
+
+    /**
+     * Sets the version field mapping used for versioning. Sets the default
+     * value to use depending on the column type.
+     *
+     * @param array $mapping   The version field mapping array
+     */
+    public function setVersionMapping(array &$mapping)
+    {
+        $this->isVersioned = true;
+        $this->versionField = $mapping['fieldName'];
+
+        if ( ! isset($mapping['default'])) {
+            if (in_array($mapping['type'], array('integer', 'bigint', 'smallint'))) {
+                $mapping['default'] = 1;
+            } else if ($mapping['type'] == 'datetime') {
+                $mapping['default'] = 'CURRENT_TIMESTAMP';
+            } else {
+                throw MappingException::unsupportedOptimisticLockingType($this->name, $mapping['fieldName'], $mapping['type']);
+            }
+        }
+    }
+
+    /**
+     * Sets whether this class is to be versioned for optimistic locking.
+     *
+     * @param boolean $bool
+     */
+    public function setVersioned($bool)
+    {
+        $this->isVersioned = $bool;
+    }
+
+    /**
+     * Sets the name of the field that is to be used for versioning if this class is
+     * versioned for optimistic locking.
+     *
+     * @param string $versionField
+     */
+    public function setVersionField($versionField)
+    {
+        $this->versionField = $versionField;
+    }
+
+    /**
+     * Mark this class as read only, no change tracking is applied to it.
+     *
+     * @return void
+     */
+    public function markReadOnly()
+    {
+        $this->isReadOnly = true;
+    }
+
+    /**
+     * A numerically indexed list of field names of this persistent class.
+     *
+     * This array includes identifier fields if present on this class.
+     *
+     * @return array
+     */
+    public function getFieldNames()
+    {
+        return array_keys($this->fieldMappings);
+    }
+
+    /**
+     * A numerically indexed list of association names of this persistent class.
+     *
+     * This array includes identifier associations if present on this class.
+     *
+     * @return array
+     */
+    public function getAssociationNames()
+    {
+        return array_keys($this->associationMappings);
+    }
+
+    /**
+     * Returns the target class name of the given association.
+     *
+     * @param string $assocName
+     * @return string
+     */
+    public function getAssociationTargetClass($assocName)
+    {
+        if ( ! isset($this->associationMappings[$assocName])) {
+            throw new \InvalidArgumentException("Association name expected, '" . $assocName ."' is not an association.");
+        }
+
+        return $this->associationMappings[$assocName]['targetEntity'];
+    }
+
+    /**
+     * Get fully-qualified class name of this persistent class.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
+     *
+     * @param AbstractPlatform $platform
+     * @return array
+     */
+    public function getQuotedIdentifierColumnNames($platform)
+    {
+        $quotedColumnNames = array();
+
+        foreach ($this->identifier as $idProperty) {
+            if (isset($this->fieldMappings[$idProperty])) {
+                $quotedColumnNames[] = isset($this->fieldMappings[$idProperty]['quoted'])
+                    ? $platform->quoteIdentifier($this->fieldMappings[$idProperty]['columnName'])
+                    : $this->fieldMappings[$idProperty]['columnName'];
+
+                continue;
+            }
+
+            // Association defined as Id field
+            $joinColumns            = $this->associationMappings[$idProperty]['joinColumns'];
+            $assocQuotedColumnNames = array_map(
+                function ($joinColumn) {
+                    return isset($joinColumn['quoted'])
+                        ? $platform->quoteIdentifier($joinColumn['name'])
+                        : $joinColumn['name'];
+                },
+                $joinColumns
+            );
+
+            $quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames);
+        }
+
+        return $quotedColumnNames;
+    }
+
+    /**
+     * Gets the (possibly quoted) column name of a mapped field for safe use
+     * in an SQL statement.
+     *
+     * @param string $field
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function getQuotedColumnName($field, $platform)
+    {
+        return isset($this->fieldMappings[$field]['quoted'])
+            ? $platform->quoteIdentifier($this->fieldMappings[$field]['columnName'])
+            : $this->fieldMappings[$field]['columnName'];
+    }
+
+    /**
+     * Gets the (possibly quoted) primary table name of this class for safe use
+     * in an SQL statement.
+     *
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function getQuotedTableName($platform)
+    {
+        return isset($this->table['quoted']) ? $platform->quoteIdentifier($this->table['name']) : $this->table['name'];
+    }
+
+    /**
+     * Gets the (possibly quoted) name of the join table.
+     *
+     * @param AbstractPlatform $platform
+     * @return string
+     */
+    public function getQuotedJoinTableName(array $assoc, $platform)
+    {
+        return isset($assoc['joinTable']['quoted']) ? $platform->quoteIdentifier($assoc['joinTable']['name']) : $assoc['joinTable']['name'];
+    }
+
+    /**
+     * @param string $fieldName
+     * @return bool
+     */
+    public function isAssociationInverseSide($fieldName)
+    {
+        return isset($this->associationMappings[$fieldName]) && ! $this->associationMappings[$fieldName]['isOwningSide'];
+    }
+
+    /**
+     * @param string $fieldName
+     * @return string
+     */
+    public function getAssociationMappedByTargetField($fieldName)
+    {
+        return $this->associationMappings[$fieldName]['mappedBy'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Column.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Column.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Column.php	(revision 345)
@@ -0,0 +1,46 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class Column implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var mixed */
+    public $type = 'string';
+    /** @var integer */
+    public $length;
+    /** @var integer */
+    public $precision = 0; // The precision for a decimal (exact numeric) column (Applies only for decimal column)
+    /** @var integer */
+    public $scale = 0; // The scale for a decimal (exact numeric) column (Applies only for decimal column)
+    /** @var boolean */
+    public $unique = false;
+    /** @var boolean */
+    public $nullable = false;
+    /** @var array */
+    public $options = array();
+    /** @var string */
+    public $columnDefinition;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorColumn.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorColumn.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorColumn.php	(revision 345)
@@ -0,0 +1,36 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class DiscriminatorColumn implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var string */
+    public $type;
+    /** @var integer */
+    public $length;
+    /** @var mixed */
+    public $fieldName; // field name used in non-object hydration (array/scalar)
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorMap.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorMap.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/DiscriminatorMap.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class DiscriminatorMap implements Annotation
+{
+    /** @var array<string> */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php	(revision 345)
@@ -0,0 +1,213 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * Base driver for file-based metadata drivers.
+ *
+ * A file driver operates in a mode where it loads the mapping files of individual
+ * classes on demand. This requires the user to adhere to the convention of 1 mapping
+ * file per class and the file names of the mapping files must correspond to the full
+ * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.0
+ * @version     $Revision$
+ * @author		Benjamin Eberlei <kontakt@beberlei.de>
+ * @author		Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+abstract class AbstractFileDriver implements Driver
+{
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $_paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $_fileExtension;
+
+    /**
+     * Initializes a new FileDriver that looks in the given path(s) for mapping
+     * documents and operates in the specified operating mode.
+     *
+     * @param string|array $paths One or multiple paths where mapping documents can be found.
+     */
+    public function __construct($paths)
+    {
+        $this->addPaths((array) $paths);
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->_paths = array_unique(array_merge($this->_paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->_paths;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->_fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->_fileExtension = $fileExtension;
+    }
+
+    /**
+     * Get the element of schema meta data for the class from the mapping file.
+     * This will lazily load the mapping file if it is not loaded yet
+     *
+     * @return array $element  The element of schema meta data
+     */
+    public function getElement($className)
+    {
+        $result = $this->_loadMappingFile($this->_findMappingFile($className));
+
+        if(!isset($result[$className])){
+            throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->_fileExtension);
+        }
+        return $result[$className];
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
+
+        // Check whether file exists
+        foreach ((array) $this->_paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        $classes = array();
+
+        if ($this->_paths) {
+            foreach ((array) $this->_paths as $path) {
+                if ( ! is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    $classes[] = str_replace('.', '\\', $fileName);
+                }
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * Finds the mapping file for the class with the given name by searching
+     * through the configured paths.
+     *
+     * @param $className
+     * @return string The (absolute) file name.
+     * @throws MappingException
+     */
+    protected function _findMappingFile($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
+
+        // Check whether file exists
+        foreach ((array) $this->_paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return $path . DIRECTORY_SEPARATOR . $fileName;
+            }
+        }
+
+        throw MappingException::mappingFileNotFound($className, $fileName);
+    }
+
+    /**
+     * Loads a mapping file with the given name and returns a map
+     * from class/entity names to their corresponding elements.
+     *
+     * @param string $file The mapping file to load.
+     * @return array
+     */
+    abstract protected function _loadMappingFile($file);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php	(revision 345)
@@ -0,0 +1,599 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\Common\Annotations\AnnotationRegistry,
+    Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * The AnnotationDriver reads the mapping metadata from docblock annotations.
+ *
+ * @since 2.0
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class AnnotationDriver implements Driver
+{
+    /**
+     * The AnnotationReader.
+     *
+     * @var AnnotationReader
+     */
+    protected $_reader;
+
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $_paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $_fileExtension = '.php';
+
+    /**
+     * @param array
+     */
+    protected $_classNames;
+
+    /**
+     * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
+     * docblock annotations.
+     *
+     * @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
+     * @param string|array $paths One or multiple paths where mapping classes can be found.
+     */
+    public function __construct($reader, $paths = null)
+    {
+        $this->_reader = $reader;
+        if ($paths) {
+            $this->addPaths((array) $paths);
+        }
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->_paths = array_unique(array_merge($this->_paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->_paths;
+    }
+
+    /**
+     * Retrieve the current annotation reader
+     *
+     * @return AnnotationReader
+     */
+    public function getReader()
+    {
+        return $this->_reader;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->_fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->_fileExtension = $fileExtension;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        $class = $metadata->getReflectionClass();
+        if (!$class) {
+            // this happens when running annotation driver in combination with
+            // static reflection services. This is not the nicest fix
+            $class = new \ReflectionClass($metadata->name);
+        }
+
+        $classAnnotations = $this->_reader->getClassAnnotations($class);
+
+        if ($classAnnotations) {
+            foreach ($classAnnotations as $key => $annot) {
+                if ( ! is_numeric($key)) {
+                    continue;
+                }
+
+                $classAnnotations[get_class($annot)] = $annot;
+            }
+        }
+
+        // Evaluate Entity annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) {
+            $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity'];
+            if ($entityAnnot->repositoryClass !== null) {
+                $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
+            }
+            if ($entityAnnot->readOnly) {
+                $metadata->markReadOnly();
+            }
+        } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
+            $mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'];
+            $metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass);
+            $metadata->isMappedSuperclass = true;
+        } else {
+            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
+        }
+
+        // Evaluate Table annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) {
+            $tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table'];
+            $primaryTable = array(
+                'name' => $tableAnnot->name,
+                'schema' => $tableAnnot->schema
+            );
+
+            if ($tableAnnot->indexes !== null) {
+                foreach ($tableAnnot->indexes as $indexAnnot) {
+                    $index = array('columns' => $indexAnnot->columns);
+
+                    if ( ! empty($indexAnnot->name)) {
+                        $primaryTable['indexes'][$indexAnnot->name] = $index;
+                    } else {
+                        $primaryTable['indexes'][] = $index;
+                    }
+                }
+            }
+
+            if ($tableAnnot->uniqueConstraints !== null) {
+                foreach ($tableAnnot->uniqueConstraints as $uniqueConstraintAnnot) {
+                    $uniqueConstraint = array('columns' => $uniqueConstraintAnnot->columns);
+
+                    if ( ! empty($uniqueConstraintAnnot->name)) {
+                        $primaryTable['uniqueConstraints'][$uniqueConstraintAnnot->name] = $uniqueConstraint;
+                    } else {
+                        $primaryTable['uniqueConstraints'][] = $uniqueConstraint;
+                    }
+                }
+            }
+
+            $metadata->setPrimaryTable($primaryTable);
+        }
+
+        // Evaluate NamedQueries annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
+            $namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
+
+            if (!is_array($namedQueriesAnnot->value)) {
+                throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
+            }
+
+            foreach ($namedQueriesAnnot->value as $namedQuery) {
+                if (!($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
+                    throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
+                }
+                $metadata->addNamedQuery(array(
+                    'name'  => $namedQuery->name,
+                    'query' => $namedQuery->query
+                ));
+            }
+        }
+
+        // Evaluate InheritanceType annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
+            $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
+            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value));
+
+            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
+                // Evaluate DiscriminatorColumn annotation
+                if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) {
+                    $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'];
+                    $metadata->setDiscriminatorColumn(array(
+                        'name' => $discrColumnAnnot->name,
+                        'type' => $discrColumnAnnot->type,
+                        'length' => $discrColumnAnnot->length
+                    ));
+                } else {
+                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
+                }
+
+                // Evaluate DiscriminatorMap annotation
+                if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) {
+                    $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'];
+                    $metadata->setDiscriminatorMap($discrMapAnnot->value);
+                }
+            }
+        }
+
+
+        // Evaluate DoctrineChangeTrackingPolicy annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) {
+            $changeTrackingAnnot = $classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'];
+            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value));
+        }
+
+        // Evaluate annotations on properties/fields
+        foreach ($class->getProperties() as $property) {
+            if ($metadata->isMappedSuperclass && ! $property->isPrivate()
+                ||
+                $metadata->isInheritedField($property->name)
+                ||
+                $metadata->isInheritedAssociation($property->name)) {
+                continue;
+            }
+
+            $mapping = array();
+            $mapping['fieldName'] = $property->getName();
+
+            // Check for JoinColummn/JoinColumns annotations
+            $joinColumns = array();
+
+            if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
+                $joinColumns[] = array(
+                    'name' => $joinColumnAnnot->name,
+                    'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
+                    'unique' => $joinColumnAnnot->unique,
+                    'nullable' => $joinColumnAnnot->nullable,
+                    'onDelete' => $joinColumnAnnot->onDelete,
+                    'columnDefinition' => $joinColumnAnnot->columnDefinition,
+                );
+            } else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
+                foreach ($joinColumnsAnnot->value as $joinColumn) {
+                    $joinColumns[] = array(
+                        'name' => $joinColumn->name,
+                        'referencedColumnName' => $joinColumn->referencedColumnName,
+                        'unique' => $joinColumn->unique,
+                        'nullable' => $joinColumn->nullable,
+                        'onDelete' => $joinColumn->onDelete,
+                        'columnDefinition' => $joinColumn->columnDefinition,
+                    );
+                }
+            }
+
+            // Field can only be annotated with one of:
+            // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
+            if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
+                if ($columnAnnot->type == null) {
+                    throw MappingException::propertyTypeIsRequired($className, $property->getName());
+                }
+
+                $mapping['type'] = $columnAnnot->type;
+                $mapping['length'] = $columnAnnot->length;
+                $mapping['precision'] = $columnAnnot->precision;
+                $mapping['scale'] = $columnAnnot->scale;
+                $mapping['nullable'] = $columnAnnot->nullable;
+                $mapping['unique'] = $columnAnnot->unique;
+                if ($columnAnnot->options) {
+                    $mapping['options'] = $columnAnnot->options;
+                }
+
+                if (isset($columnAnnot->name)) {
+                    $mapping['columnName'] = $columnAnnot->name;
+                }
+
+                if (isset($columnAnnot->columnDefinition)) {
+                    $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
+                }
+
+                if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
+                    $mapping['id'] = true;
+                }
+
+                if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
+                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
+                }
+
+                if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
+                    $metadata->setVersionMapping($mapping);
+                }
+
+                $metadata->mapField($mapping);
+
+                // Check for SequenceGenerator/TableGenerator definition
+                if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
+                    $metadata->setSequenceGeneratorDefinition(array(
+                        'sequenceName' => $seqGeneratorAnnot->sequenceName,
+                        'allocationSize' => $seqGeneratorAnnot->allocationSize,
+                        'initialValue' => $seqGeneratorAnnot->initialValue
+                    ));
+                } else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
+                    throw MappingException::tableIdGeneratorNotImplemented($className);
+                }
+            } else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
+                if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
+                    $mapping['id'] = true;
+                }
+
+                $mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
+                $mapping['joinColumns'] = $joinColumns;
+                $mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
+                $mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
+                $mapping['cascade'] = $oneToOneAnnot->cascade;
+                $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
+                $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch);
+                $metadata->mapOneToOne($mapping);
+            } else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
+                $mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
+                $mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
+                $mapping['cascade'] = $oneToManyAnnot->cascade;
+                $mapping['indexBy'] = $oneToManyAnnot->indexBy;
+                $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
+                $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch);
+
+                if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
+                    $mapping['orderBy'] = $orderByAnnot->value;
+                }
+
+                $metadata->mapOneToMany($mapping);
+            } else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
+                if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
+                    $mapping['id'] = true;
+                }
+
+                $mapping['joinColumns'] = $joinColumns;
+                $mapping['cascade'] = $manyToOneAnnot->cascade;
+                $mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
+                $mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
+                $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch);
+                $metadata->mapManyToOne($mapping);
+            } else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
+                $joinTable = array();
+
+                if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
+                    $joinTable = array(
+                        'name' => $joinTableAnnot->name,
+                        'schema' => $joinTableAnnot->schema
+                    );
+
+                    foreach ($joinTableAnnot->joinColumns as $joinColumn) {
+                        $joinTable['joinColumns'][] = array(
+                            'name' => $joinColumn->name,
+                            'referencedColumnName' => $joinColumn->referencedColumnName,
+                            'unique' => $joinColumn->unique,
+                            'nullable' => $joinColumn->nullable,
+                            'onDelete' => $joinColumn->onDelete,
+                            'columnDefinition' => $joinColumn->columnDefinition,
+                        );
+                    }
+
+                    foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
+                        $joinTable['inverseJoinColumns'][] = array(
+                            'name' => $joinColumn->name,
+                            'referencedColumnName' => $joinColumn->referencedColumnName,
+                            'unique' => $joinColumn->unique,
+                            'nullable' => $joinColumn->nullable,
+                            'onDelete' => $joinColumn->onDelete,
+                            'columnDefinition' => $joinColumn->columnDefinition,
+                        );
+                    }
+                }
+
+                $mapping['joinTable'] = $joinTable;
+                $mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
+                $mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
+                $mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
+                $mapping['cascade'] = $manyToManyAnnot->cascade;
+                $mapping['indexBy'] = $manyToManyAnnot->indexBy;
+                $mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval;
+                $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch);
+
+                if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
+                    $mapping['orderBy'] = $orderByAnnot->value;
+                }
+
+                $metadata->mapManyToMany($mapping);
+            }
+        }
+
+        // Evaluate @HasLifecycleCallbacks annotation
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
+            foreach ($class->getMethods() as $method) {
+                // filter for the declaring class only, callbacks from parents will already be registered.
+                if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
+                    $annotations = $this->_reader->getMethodAnnotations($method);
+
+                    if ($annotations) {
+                        foreach ($annotations as $key => $annot) {
+                            if ( ! is_numeric($key)) {
+                                continue;
+                            }
+                            $annotations[get_class($annot)] = $annot;
+                        }
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
+                    }
+
+                    if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) {
+                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Whether the class with the specified name is transient. Only non-transient
+     * classes, that is entities and mapped superclasses, should have their metadata loaded.
+     * A class is non-transient if it is annotated with either @Entity or
+     * @MappedSuperclass in the class doc block.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        $classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className));
+
+        if ($classAnnotations && is_numeric(key($classAnnotations))) {
+            foreach ($classAnnotations as $annot) {
+                if ($annot instanceof \Doctrine\ORM\Mapping\Entity) {
+                    return false;
+                }
+                if ($annot instanceof \Doctrine\ORM\Mapping\MappedSuperclass) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) &&
+               ! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames()
+    {
+        if ($this->_classNames !== null) {
+            return $this->_classNames;
+        }
+
+        if (!$this->_paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->_paths as $path) {
+            if ( ! is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RegexIterator(
+                new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                ),
+                '/^.+' . str_replace('.', '\.', $this->_fileExtension) . '$/i',
+                \RecursiveRegexIterator::GET_MATCH
+            );
+
+            foreach ($iterator as $file) {
+                $sourceFile = realpath($file[0]);
+
+                require_once $sourceFile;
+
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->_classNames = $classes;
+
+        return $classes;
+    }
+
+    /**
+     * Attempts to resolve the fetch mode.
+     *
+     * @param string $className The class name
+     * @param string $fetchMode The fetch mode
+     * @return integer The fetch mode as defined in ClassMetadata
+     * @throws MappingException If the fetch mode is not valid
+     */
+    private function getFetchMode($className, $fetchMode)
+    {
+        if(!defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
+            throw MappingException::invalidFetchMode($className,  $fetchMode);
+        }
+
+        return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode);
+    }
+    /**
+     * Factory method for the Annotation Driver
+     *
+     * @param array|string $paths
+     * @param AnnotationReader $reader
+     * @return AnnotationDriver
+     */
+    static public function create($paths = array(), AnnotationReader $reader = null)
+    {
+        if ($reader == null) {
+            $reader = new AnnotationReader();
+            $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
+        }
+        return new self($reader, $paths);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php	(revision 345)
@@ -0,0 +1,417 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\DBAL\Schema\AbstractSchemaManager,
+    Doctrine\DBAL\Schema\SchemaException,
+    Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException,
+    Doctrine\Common\Util\Inflector;
+
+/**
+ * The DatabaseDriver reverse engineers the mapping metadata from a database.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DatabaseDriver implements Driver
+{
+    /**
+     * @var AbstractSchemaManager
+     */
+    private $_sm;
+
+    /**
+     * @var array
+     */
+    private $tables = null;
+
+    private $classToTableNames = array();
+
+    /**
+     * @var array
+     */
+    private $manyToManyTables = array();
+
+    /**
+     * @var array
+     */
+    private $classNamesForTables = array();
+
+    /**
+     * @var array
+     */
+    private $fieldNamesForColumns = array();
+
+    /**
+     * The namespace for the generated entities.
+     *
+     * @var string
+     */
+    private $namespace;
+
+    /**
+     * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
+     * docblock annotations.
+     *
+     * @param AnnotationReader $reader The AnnotationReader to use.
+     */
+    public function __construct(AbstractSchemaManager $schemaManager)
+    {
+        $this->_sm = $schemaManager;
+    }
+
+    /**
+     * Set tables manually instead of relying on the reverse engeneering capabilities of SchemaManager.
+     *
+     * @param array $entityTables
+     * @param array $manyToManyTables
+     * @return void
+     */
+    public function setTables($entityTables, $manyToManyTables)
+    {
+        $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
+        foreach ($entityTables AS $table) {
+            $className = $this->getClassNameForTable($table->getName());
+            $this->classToTableNames[$className] = $table->getName();
+            $this->tables[$table->getName()] = $table;
+        }
+        foreach ($manyToManyTables AS $table) {
+            $this->manyToManyTables[$table->getName()] = $table;
+        }
+    }
+
+    private function reverseEngineerMappingFromDatabase()
+    {
+        if ($this->tables !== null) {
+            return;
+        }
+
+        $tables = array();
+
+        foreach ($this->_sm->listTableNames() as $tableName) {
+            $tables[$tableName] = $this->_sm->listTableDetails($tableName);
+        }
+
+        $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
+        foreach ($tables AS $tableName => $table) {
+            /* @var $table Table */
+            if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
+                $foreignKeys = $table->getForeignKeys();
+            } else {
+                $foreignKeys = array();
+            }
+
+            $allForeignKeyColumns = array();
+            foreach ($foreignKeys AS $foreignKey) {
+                $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
+            }
+
+            if ( ! $table->hasPrimaryKey()) {
+                throw new MappingException(
+                    "Table " . $table->getName() . " has no primary key. Doctrine does not ".
+                    "support reverse engineering from tables that don't have a primary key."
+                );
+            }
+
+            $pkColumns = $table->getPrimaryKey()->getColumns();
+            sort($pkColumns);
+            sort($allForeignKeyColumns);
+
+            if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
+                $this->manyToManyTables[$tableName] = $table;
+            } else {
+                // lower-casing is necessary because of Oracle Uppercase Tablenames,
+                // assumption is lower-case + underscore separated.
+                $className = $this->getClassNameForTable($tableName);
+                $this->tables[$tableName] = $table;
+                $this->classToTableNames[$className] = $tableName;
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        $this->reverseEngineerMappingFromDatabase();
+
+        if (!isset($this->classToTableNames[$className])) {
+            throw new \InvalidArgumentException("Unknown class " . $className);
+        }
+
+        $tableName = $this->classToTableNames[$className];
+
+        $metadata->name = $className;
+        $metadata->table['name'] = $tableName;
+
+        $columns = $this->tables[$tableName]->getColumns();
+        $indexes = $this->tables[$tableName]->getIndexes();
+        try {
+            $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns();
+        } catch(SchemaException $e) {
+            $primaryKeyColumns = array();
+        }
+
+        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
+            $foreignKeys = $this->tables[$tableName]->getForeignKeys();
+        } else {
+            $foreignKeys = array();
+        }
+
+        $allForeignKeyColumns = array();
+        foreach ($foreignKeys AS $foreignKey) {
+            $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
+        }
+
+        $ids = array();
+        $fieldMappings = array();
+        foreach ($columns as $column) {
+            $fieldMapping = array();
+            
+            if (in_array($column->getName(), $allForeignKeyColumns)) {
+                continue;
+            } else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
+                $fieldMapping['id'] = true;
+            }
+            
+            $fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
+            $fieldMapping['columnName'] = $column->getName();
+            $fieldMapping['type'] = strtolower((string) $column->getType());
+
+            if ($column->getType() instanceof \Doctrine\DBAL\Types\StringType) {
+                $fieldMapping['length'] = $column->getLength();
+                $fieldMapping['fixed'] = $column->getFixed();
+            } else if ($column->getType() instanceof \Doctrine\DBAL\Types\IntegerType) {
+                $fieldMapping['unsigned'] = $column->getUnsigned();
+            }
+            $fieldMapping['nullable'] = $column->getNotNull() ? false : true;
+
+            if (isset($fieldMapping['id'])) {
+                $ids[] = $fieldMapping;
+            } else {
+                $fieldMappings[] = $fieldMapping;
+            }
+        }
+
+        if ($ids) {
+            if (count($ids) == 1) {
+                $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+            }
+
+            foreach ($ids as $id) {
+                $metadata->mapField($id);
+            }
+        }
+
+        foreach ($fieldMappings as $fieldMapping) {
+            $metadata->mapField($fieldMapping);
+        }
+
+        foreach ($this->manyToManyTables AS $manyTable) {
+            foreach ($manyTable->getForeignKeys() AS $foreignKey) {
+                // foreign  key maps to the table of the current entity, many to many association probably exists
+                if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) {
+                    $myFk = $foreignKey;
+                    $otherFk = null;
+                    foreach ($manyTable->getForeignKeys() AS $foreignKey) {
+                        if ($foreignKey != $myFk) {
+                            $otherFk = $foreignKey;
+                            break;
+                        }
+                    }
+
+                    if (!$otherFk) {
+                        // the definition of this many to many table does not contain
+                        // enough foreign key information to continue reverse engeneering.
+                        continue;
+                    }
+
+                    $localColumn = current($myFk->getColumns());
+                    $associationMapping = array();
+                    $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true);
+                    $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
+                    if (current($manyTable->getColumns())->getName() == $localColumn) {
+                        $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
+                        $associationMapping['joinTable'] = array(
+                            'name' => strtolower($manyTable->getName()),
+                            'joinColumns' => array(),
+                            'inverseJoinColumns' => array(),
+                        );
+
+                        $fkCols = $myFk->getForeignColumns();
+                        $cols = $myFk->getColumns();
+                        for ($i = 0; $i < count($cols); $i++) {
+                            $associationMapping['joinTable']['joinColumns'][] = array(
+                                'name' => $cols[$i],
+                                'referencedColumnName' => $fkCols[$i],
+                            );
+                        }
+
+                        $fkCols = $otherFk->getForeignColumns();
+                        $cols = $otherFk->getColumns();
+                        for ($i = 0; $i < count($cols); $i++) {
+                            $associationMapping['joinTable']['inverseJoinColumns'][] = array(
+                                'name' => $cols[$i],
+                                'referencedColumnName' => $fkCols[$i],
+                            );
+                        }
+                    } else {
+                        $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
+                    }
+                    $metadata->mapManyToMany($associationMapping);
+                    break;
+                }
+            }
+        }
+
+        foreach ($foreignKeys as $foreignKey) {
+            $foreignTable = $foreignKey->getForeignTableName();
+            $cols = $foreignKey->getColumns();
+            $fkCols = $foreignKey->getForeignColumns();
+
+            $localColumn = current($cols);
+            $associationMapping = array();
+            $associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true);
+            $associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable);
+
+            if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) {
+                $associationMapping['id'] = true;
+            }
+
+            for ($i = 0; $i < count($cols); $i++) {
+                $associationMapping['joinColumns'][] = array(
+                    'name' => $cols[$i],
+                    'referencedColumnName' => $fkCols[$i],
+                );
+            }
+            
+            //Here we need to check if $cols are the same as $primaryKeyColums
+            if (!array_diff($cols,$primaryKeyColumns)) {
+                $metadata->mapOneToOne($associationMapping);
+            } else {
+                $metadata->mapManyToOne($associationMapping);
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isTransient($className)
+    {
+        return true;
+    }
+
+    /**
+     * Return all the class names supported by this driver.
+     *
+     * IMPORTANT: This method must return an array of class not tables names.
+     *
+     * @return array
+     */
+    public function getAllClassNames()
+    {
+        $this->reverseEngineerMappingFromDatabase();
+
+        return array_keys($this->classToTableNames);
+    }
+
+    /**
+     * Set class name for a table.
+     *
+     * @param string $tableName
+     * @param string $className
+     * @return void
+     */
+    public function setClassNameForTable($tableName, $className)
+    {
+        $this->classNamesForTables[$tableName] = $className;
+    }
+
+    /**
+     * Set field name for a column on a specific table.
+     *
+     * @param string $tableName
+     * @param string $columnName
+     * @param string $fieldName
+     * @return void
+     */
+    public function setFieldNameForColumn($tableName, $columnName, $fieldName)
+    {
+        $this->fieldNamesForColumns[$tableName][$columnName] = $fieldName;
+    }
+
+    /**
+     * Return the mapped class name for a table if it exists. Otherwise return "classified" version.
+     *
+     * @param string $tableName
+     * @return string
+     */
+    private function getClassNameForTable($tableName)
+    {
+        if (isset($this->classNamesForTables[$tableName])) {
+            return $this->namespace . $this->classNamesForTables[$tableName];
+        }
+
+        return $this->namespace . Inflector::classify(strtolower($tableName));
+    }
+
+    /**
+     * Return the mapped field name for a column, if it exists. Otherwise return camelized version.
+     *
+     * @param string $tableName
+     * @param string $columnName
+     * @param boolean $fk Whether the column is a foreignkey or not.
+     * @return string
+     */
+    private function getFieldNameForColumn($tableName, $columnName, $fk = false)
+    {
+        if (isset($this->fieldNamesForColumns[$tableName]) && isset($this->fieldNamesForColumns[$tableName][$columnName])) {
+            return $this->fieldNamesForColumns[$tableName][$columnName];
+        }
+
+        $columnName = strtolower($columnName);
+
+        // Replace _id if it is a foreignkey column
+        if ($fk) {
+            $columnName = str_replace('_id', '', $columnName);
+        }
+        return Inflector::camelize($columnName);
+    }
+
+    /**
+     * Set the namespace for the generated entities.
+     *
+     * @param string $namespace
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace = $namespace;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+require_once __DIR__.'/../Annotation.php';
+require_once __DIR__.'/../Entity.php';
+require_once __DIR__.'/../MappedSuperclass.php';
+require_once __DIR__.'/../InheritanceType.php';
+require_once __DIR__.'/../DiscriminatorColumn.php';
+require_once __DIR__.'/../DiscriminatorMap.php';
+require_once __DIR__.'/../Id.php';
+require_once __DIR__.'/../GeneratedValue.php';
+require_once __DIR__.'/../Version.php';
+require_once __DIR__.'/../JoinColumn.php';
+require_once __DIR__.'/../JoinColumns.php';
+require_once __DIR__.'/../Column.php';
+require_once __DIR__.'/../OneToOne.php';
+require_once __DIR__.'/../OneToMany.php';
+require_once __DIR__.'/../ManyToOne.php';
+require_once __DIR__.'/../ManyToMany.php';
+require_once __DIR__.'/../ElementCollection.php';
+require_once __DIR__.'/../Table.php';
+require_once __DIR__.'/../UniqueConstraint.php';
+require_once __DIR__.'/../Index.php';
+require_once __DIR__.'/../JoinTable.php';
+require_once __DIR__.'/../SequenceGenerator.php';
+require_once __DIR__.'/../ChangeTrackingPolicy.php';
+require_once __DIR__.'/../OrderBy.php';
+require_once __DIR__.'/../NamedQueries.php';
+require_once __DIR__.'/../NamedQuery.php';
+require_once __DIR__.'/../HasLifecycleCallbacks.php';
+require_once __DIR__.'/../PrePersist.php';
+require_once __DIR__.'/../PostPersist.php';
+require_once __DIR__.'/../PreUpdate.php';
+require_once __DIR__.'/../PostUpdate.php';
+require_once __DIR__.'/../PreRemove.php';
+require_once __DIR__.'/../PostRemove.php';
+require_once __DIR__.'/../PostLoad.php';
+require_once __DIR__.'/../PreFlush.php';
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/Driver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/Driver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/Driver.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * Contract for metadata drivers.
+ *
+ * @since 2.0
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @todo Rename: MetadataDriver or MappingDriver
+ */
+interface Driver
+{
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadataInfo $metadata
+     */
+    function loadMetadataForClass($className, ClassMetadataInfo $metadata);
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    function getAllClassNames();
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    function isTransient($className);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DriverChain.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DriverChain.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/DriverChain.php	(revision 345)
@@ -0,0 +1,126 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\Driver\Driver,
+    Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * The DriverChain allows you to add multiple other mapping drivers for
+ * certain namespaces
+ *
+ * @since 2.0
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @todo Rename: MappingDriverChain or MetadataDriverChain
+ */
+class DriverChain implements Driver
+{
+    /**
+     * @var array
+     */
+    private $_drivers = array();
+
+    /**
+     * Add a nested driver.
+     *
+     * @param Driver $nestedDriver
+     * @param string $namespace
+     */
+    public function addDriver(Driver $nestedDriver, $namespace)
+    {
+        $this->_drivers[$namespace] = $nestedDriver;
+    }
+
+    /**
+     * Get the array of nested drivers.
+     *
+     * @return array $drivers
+     */
+    public function getDrivers()
+    {
+        return $this->_drivers;
+    }
+
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadataInfo $metadata
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        foreach ($this->_drivers as $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                $driver->loadMetadataForClass($className, $metadata);
+                return;
+            }
+        }
+
+        throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        $classNames = array();
+        $driverClasses = array();
+        foreach ($this->_drivers AS $namespace => $driver) {
+            $oid = spl_object_hash($driver);
+            if (!isset($driverClasses[$oid])) {
+                $driverClasses[$oid] = $driver->getAllClassNames();
+            }
+
+            foreach ($driverClasses[$oid] AS $className) {
+                if (strpos($className, $namespace) === 0) {
+                    $classNames[$className] = true;
+                }
+            }
+        }
+        return array_keys($classNames);
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     *
+     * This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        foreach ($this->_drivers AS $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                return $driver->isTransient($className);
+            }
+        }
+
+        // class isTransient, i.e. not an entity or mapped superclass
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/PHPDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/PHPDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/PHPDriver.php	(revision 345)
@@ -0,0 +1,69 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\DBAL\Schema\AbstractSchemaManager,
+    Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException,
+    Doctrine\Common\Util\Inflector,
+    Doctrine\ORM\Mapping\Driver\AbstractFileDriver;
+
+/**
+ * The PHPDriver includes php files which just populate ClassMetadataInfo
+ * instances with plain php code
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.0
+ * @version     $Revision$
+ * @author		Benjamin Eberlei <kontakt@beberlei.de>
+ * @author		Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @todo Rename: PHPDriver
+ */
+class PHPDriver extends AbstractFileDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $_fileExtension = '.php';
+    protected $_metadata;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        $this->_metadata = $metadata;
+        $this->_loadMappingFile($this->_findMappingFile($className));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _loadMappingFile($file)
+    {
+        $metadata = $this->_metadata;
+        include $file;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php	(revision 345)
@@ -0,0 +1,176 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * XmlDriver that additionally looks for mapping information in a global file.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @license MIT
+ */
+class SimplifiedXmlDriver extends XmlDriver
+{
+    protected $_prefixes = array();
+    protected $_globalBasename;
+    protected $_classCache;
+    protected $_fileExtension = '.orm.xml';
+
+    public function __construct($prefixes)
+    {
+        $this->addNamespacePrefixes($prefixes);
+    }
+
+    public function setGlobalBasename($file)
+    {
+        $this->_globalBasename = $file;
+    }
+
+    public function getGlobalBasename()
+    {
+        return $this->_globalBasename;
+    }
+
+    public function addNamespacePrefixes($prefixes)
+    {
+        $this->_prefixes = array_merge($this->_prefixes, $prefixes);
+        $this->addPaths(array_flip($prefixes));
+    }
+
+    public function getNamespacePrefixes()
+    {
+        return $this->_prefixes;
+    }
+
+    public function isTransient($className)
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        // The mapping is defined in the global mapping file
+        if (isset($this->_classCache[$className])) {
+            return false;
+        }
+
+        try {
+            $this->_findMappingFile($className);
+
+            return false;
+        } catch (MappingException $e) {
+            return true;
+        }
+    }
+
+    public function getAllClassNames()
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        $classes = array();
+
+        if ($this->_paths) {
+            foreach ((array) $this->_paths as $path) {
+                if (!is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->_fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    if (isset($this->_prefixes[$path])) {
+                        $classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
+                    } else {
+                        $classes[] = str_replace('.', '\\', $fileName);
+                    }
+                }
+            }
+        }
+
+        return array_merge($classes, array_keys($this->_classCache));
+    }
+
+    public function getElement($className)
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        if (!isset($this->_classCache[$className])) {
+            $this->_classCache[$className] = parent::getElement($className);
+        }
+
+        return $this->_classCache[$className];
+    }
+
+    protected function initialize()
+    {
+        $this->_classCache = array();
+        if (null !== $this->_globalBasename) {
+            foreach ($this->_paths as $path) {
+                if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) {
+                    $this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file));
+                }
+            }
+        }
+    }
+
+    protected function _findMappingFile($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension;
+        foreach ($this->_paths as $path) {
+            if (!isset($this->_prefixes[$path])) {
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return $path.DIRECTORY_SEPARATOR.$defaultFileName;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->_prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension;
+            if (is_file($filename)) {
+                return $filename;
+            }
+
+            throw MappingException::mappingFileNotFound($className, $filename);
+        }
+
+        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php	(revision 345)
@@ -0,0 +1,181 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * YamlDriver that additionally looks for mapping information in a global file.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @license MIT
+ */
+class SimplifiedYamlDriver extends YamlDriver
+{
+    protected $_prefixes = array();
+    protected $_globalBasename;
+    protected $_classCache;
+    protected $_fileExtension = '.orm.yml';
+
+    public function __construct($prefixes)
+    {
+        $this->addNamespacePrefixes($prefixes);
+    }
+
+    public function setGlobalBasename($file)
+    {
+        $this->_globalBasename = $file;
+    }
+
+    public function getGlobalBasename()
+    {
+        return $this->_globalBasename;
+    }
+
+    public function addNamespacePrefixes($prefixes)
+    {
+        $this->_prefixes = array_merge($this->_prefixes, $prefixes);
+        $this->addPaths(array_flip($prefixes));
+    }
+
+    public function addNamespacePrefix($prefix, $path)
+    {
+        $this->_prefixes[$path] = $prefix;
+    }
+
+    public function getNamespacePrefixes()
+    {
+        return $this->_prefixes;
+    }
+
+    public function isTransient($className)
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        // The mapping is defined in the global mapping file
+        if (isset($this->_classCache[$className])) {
+            return false;
+        }
+
+        try {
+            $this->_findMappingFile($className);
+
+            return false;
+        } catch (MappingException $e) {
+            return true;
+        }
+    }
+
+    public function getAllClassNames()
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        $classes = array();
+
+        if ($this->_paths) {
+            foreach ((array) $this->_paths as $path) {
+                if (!is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->_fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    if (isset($this->_prefixes[$path])) {
+                        $classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
+                    } else {
+                        $classes[] = str_replace('.', '\\', $fileName);
+                    }
+                }
+            }
+        }
+
+        return array_merge($classes, array_keys($this->_classCache));
+    }
+
+    public function getElement($className)
+    {
+        if (null === $this->_classCache) {
+            $this->initialize();
+        }
+
+        if (!isset($this->_classCache[$className])) {
+            $this->_classCache[$className] = parent::getElement($className);
+        }
+
+        return $this->_classCache[$className];
+    }
+
+    protected function initialize()
+    {
+        $this->_classCache = array();
+        if (null !== $this->_globalBasename) {
+            foreach ($this->_paths as $path) {
+                if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) {
+                    $this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file));
+                }
+            }
+        }
+    }
+
+    protected function _findMappingFile($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension;
+        foreach ($this->_paths as $path) {
+            if (!isset($this->_prefixes[$path])) {
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return $path.DIRECTORY_SEPARATOR.$defaultFileName;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->_prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension;
+            if (is_file($filename)) {
+                return $filename;
+            }
+
+            throw MappingException::mappingFileNotFound($className, $filename);
+        }
+
+        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php	(revision 345)
@@ -0,0 +1,138 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo,
+ Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * The StaticPHPDriver calls a static loadMetadata() method on your entity
+ * classes where you can manually populate the ClassMetadata instance.
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class StaticPHPDriver implements Driver
+{
+    /**
+     * Paths of entity directories.
+     *
+     * @var array
+     */
+    private $_paths = array();
+
+    /**
+     * Map of all class names.
+     *
+     * @var array
+     */
+    private $_classNames;
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    private $_fileExtension = '.php';
+
+    public function __construct($paths)
+    {
+        $this->addPaths((array) $paths);
+    }
+
+    public function addPaths(array $paths)
+    {
+        $this->_paths = array_unique(array_merge($this->_paths, $paths));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        call_user_func_array(array($className, 'loadMetadata'), array($metadata));
+    }
+
+    /**
+     * {@inheritDoc}
+     * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
+     */
+    public function getAllClassNames()
+    {
+        if ($this->_classNames !== null) {
+            return $this->_classNames;
+        }
+
+        if (!$this->_paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->_paths as $path) {
+            if (!is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RecursiveIteratorIterator(
+                            new \RecursiveDirectoryIterator($path),
+                            \RecursiveIteratorIterator::LEAVES_ONLY
+            );
+
+            foreach ($iterator as $file) {
+                if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
+                    continue;
+                }
+
+                $sourceFile = realpath($file->getPathName());
+                require_once $sourceFile;
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->_classNames = $classes;
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isTransient($className)
+    {
+        return method_exists($className, 'loadMetadata') ? false : true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/XmlDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/XmlDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/XmlDriver.php	(revision 345)
@@ -0,0 +1,536 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use SimpleXMLElement,
+    Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * XmlDriver is a metadata driver that enables mapping through XML files.
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.0
+ * @version     $Revision$
+ * @author		Benjamin Eberlei <kontakt@beberlei.de>
+ * @author		Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class XmlDriver extends AbstractFileDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $_fileExtension = '.dcm.xml';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        $xmlRoot = $this->getElement($className);
+
+        if ($xmlRoot->getName() == 'entity') {
+            if (isset($xmlRoot['repository-class'])) {
+                $metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
+            }
+            if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") {
+                $metadata->markReadOnly();
+            }
+        } else if ($xmlRoot->getName() == 'mapped-superclass') {
+            $metadata->setCustomRepositoryClass(
+                isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null
+            );
+            $metadata->isMappedSuperclass = true;
+        } else {
+            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
+        }
+
+        // Evaluate <entity...> attributes
+        $table = array();
+        if (isset($xmlRoot['table'])) {
+            $table['name'] = (string)$xmlRoot['table'];
+        }
+
+        $metadata->setPrimaryTable($table);
+
+        // Evaluate named queries
+        if (isset($xmlRoot['named-queries'])) {
+            foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) {
+                $metadata->addNamedQuery(array(
+                    'name'  => (string)$namedQueryElement['name'],
+                    'query' => (string)$namedQueryElement['query']
+                ));
+            }
+        }
+
+        /* not implemented specially anyway. use table = schema.table
+        if (isset($xmlRoot['schema'])) {
+            $metadata->table['schema'] = (string)$xmlRoot['schema'];
+        }*/
+
+        if (isset($xmlRoot['inheritance-type'])) {
+            $inheritanceType = (string)$xmlRoot['inheritance-type'];
+            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceType));
+
+            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
+                // Evaluate <discriminator-column...>
+                if (isset($xmlRoot->{'discriminator-column'})) {
+                    $discrColumn = $xmlRoot->{'discriminator-column'};
+                    $metadata->setDiscriminatorColumn(array(
+                        'name' => (string)$discrColumn['name'],
+                        'type' => (string)$discrColumn['type'],
+                        'length' => (string)$discrColumn['length']
+                    ));
+                } else {
+                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
+                }
+
+                // Evaluate <discriminator-map...>
+                if (isset($xmlRoot->{'discriminator-map'})) {
+                    $map = array();
+                    foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) {
+                        $map[(string)$discrMapElement['value']] = (string)$discrMapElement['class'];
+                    }
+                    $metadata->setDiscriminatorMap($map);
+                }
+            }
+        }
+
+
+        // Evaluate <change-tracking-policy...>
+        if (isset($xmlRoot['change-tracking-policy'])) {
+            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
+                    . strtoupper((string)$xmlRoot['change-tracking-policy'])));
+        }
+
+        // Evaluate <indexes...>
+        if (isset($xmlRoot->indexes)) {
+            $metadata->table['indexes'] = array();
+            foreach ($xmlRoot->indexes->index as $index) {
+                $columns = explode(',', (string)$index['columns']);
+
+                if (isset($index['name'])) {
+                    $metadata->table['indexes'][(string)$index['name']] = array(
+                        'columns' => $columns
+                    );
+                } else {
+                    $metadata->table['indexes'][] = array(
+                        'columns' => $columns
+                    );
+                }
+            }
+        }
+
+        // Evaluate <unique-constraints..>
+        if (isset($xmlRoot->{'unique-constraints'})) {
+            $metadata->table['uniqueConstraints'] = array();
+            foreach ($xmlRoot->{'unique-constraints'}->{'unique-constraint'} as $unique) {
+                $columns = explode(',', (string)$unique['columns']);
+
+                if (isset($unique['name'])) {
+                    $metadata->table['uniqueConstraints'][(string)$unique['name']] = array(
+                        'columns' => $columns
+                    );
+                } else {
+                    $metadata->table['uniqueConstraints'][] = array(
+                        'columns' => $columns
+                    );
+                }
+            }
+        }
+
+        // Evaluate <field ...> mappings
+        if (isset($xmlRoot->field)) {
+            foreach ($xmlRoot->field as $fieldMapping) {
+                $mapping = array(
+                    'fieldName' => (string)$fieldMapping['name'],
+                );
+
+                if (isset($fieldMapping['type'])) {
+                    $mapping['type'] = (string)$fieldMapping['type'];
+                }
+
+                if (isset($fieldMapping['column'])) {
+                    $mapping['columnName'] = (string)$fieldMapping['column'];
+                }
+
+                if (isset($fieldMapping['length'])) {
+                    $mapping['length'] = (int)$fieldMapping['length'];
+                }
+
+                if (isset($fieldMapping['precision'])) {
+                    $mapping['precision'] = (int)$fieldMapping['precision'];
+                }
+
+                if (isset($fieldMapping['scale'])) {
+                    $mapping['scale'] = (int)$fieldMapping['scale'];
+                }
+
+                if (isset($fieldMapping['unique'])) {
+                    $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
+                }
+
+                if (isset($fieldMapping['options'])) {
+                    $mapping['options'] = (array)$fieldMapping['options'];
+                }
+
+                if (isset($fieldMapping['nullable'])) {
+                    $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
+                }
+
+                if (isset($fieldMapping['version']) && $fieldMapping['version']) {
+                    $metadata->setVersionMapping($mapping);
+                }
+
+                if (isset($fieldMapping['column-definition'])) {
+                    $mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
+                }
+
+                $metadata->mapField($mapping);
+            }
+        }
+
+        // Evaluate <id ...> mappings
+        $associationIds = array();
+        foreach ($xmlRoot->id as $idElement) {
+            if ((bool)$idElement['association-key'] == true) {
+                $associationIds[(string)$idElement['name']] = true;
+                continue;
+            }
+
+            $mapping = array(
+                'id' => true,
+                'fieldName' => (string)$idElement['name']
+            );
+
+            if (isset($idElement['type'])) {
+                $mapping['type'] = (string)$idElement['type'];
+            }
+
+            if (isset($idElement['column'])) {
+                $mapping['columnName'] = (string)$idElement['column'];
+            }
+
+            if (isset($idElement['column-definition'])) {
+                $mapping['columnDefinition'] = (string)$idElement['column-definition'];
+            }
+
+            $metadata->mapField($mapping);
+
+            if (isset($idElement->generator)) {
+                $strategy = isset($idElement->generator['strategy']) ?
+                        (string)$idElement->generator['strategy'] : 'AUTO';
+                $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
+                        . $strategy));
+            }
+
+            // Check for SequenceGenerator/TableGenerator definition
+            if (isset($idElement->{'sequence-generator'})) {
+                $seqGenerator = $idElement->{'sequence-generator'};
+                $metadata->setSequenceGeneratorDefinition(array(
+                    'sequenceName' => (string)$seqGenerator['sequence-name'],
+                    'allocationSize' => (string)$seqGenerator['allocation-size'],
+                    'initialValue' => (string)$seqGenerator['initial-value']
+                ));
+            } else if (isset($idElement->{'table-generator'})) {
+                throw MappingException::tableIdGeneratorNotImplemented($className);
+            }
+        }
+
+        // Evaluate <one-to-one ...> mappings
+        if (isset($xmlRoot->{'one-to-one'})) {
+            foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) {
+                $mapping = array(
+                    'fieldName' => (string)$oneToOneElement['field'],
+                    'targetEntity' => (string)$oneToOneElement['target-entity']
+                );
+
+                if (isset($associationIds[$mapping['fieldName']])) {
+                    $mapping['id'] = true;
+                }
+
+                if (isset($oneToOneElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToOneElement['fetch']);
+                }
+
+                if (isset($oneToOneElement['mapped-by'])) {
+                    $mapping['mappedBy'] = (string)$oneToOneElement['mapped-by'];
+                } else {
+                    if (isset($oneToOneElement['inversed-by'])) {
+                        $mapping['inversedBy'] = (string)$oneToOneElement['inversed-by'];
+                    }
+                    $joinColumns = array();
+
+                    if (isset($oneToOneElement->{'join-column'})) {
+                        $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'});
+                    } else if (isset($oneToOneElement->{'join-columns'})) {
+                        foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
+                            $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
+                        }
+                    }
+
+                    $mapping['joinColumns'] = $joinColumns;
+                }
+
+                if (isset($oneToOneElement->cascade)) {
+                    $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade);
+                }
+
+                if (isset($oneToOneElement['orphan-removal'])) {
+                    $mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal'];
+                }
+
+                $metadata->mapOneToOne($mapping);
+            }
+        }
+
+        // Evaluate <one-to-many ...> mappings
+        if (isset($xmlRoot->{'one-to-many'})) {
+            foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) {
+                $mapping = array(
+                    'fieldName' => (string)$oneToManyElement['field'],
+                    'targetEntity' => (string)$oneToManyElement['target-entity'],
+                    'mappedBy' => (string)$oneToManyElement['mapped-by']
+                );
+
+                if (isset($oneToManyElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToManyElement['fetch']);
+                }
+
+                if (isset($oneToManyElement->cascade)) {
+                    $mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade);
+                }
+
+                if (isset($oneToManyElement['orphan-removal'])) {
+                    $mapping['orphanRemoval'] = (bool)$oneToManyElement['orphan-removal'];
+                }
+
+                if (isset($oneToManyElement->{'order-by'})) {
+                    $orderBy = array();
+                    foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
+                        $orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
+                    }
+                    $mapping['orderBy'] = $orderBy;
+                }
+
+                if (isset($oneToManyElement['index-by'])) {
+                    $mapping['indexBy'] = (string)$oneToManyElement['index-by'];
+                } else if (isset($oneToManyElement->{'index-by'})) {
+                    throw new \InvalidArgumentException("<index-by /> is not a valid tag");
+                }
+
+                $metadata->mapOneToMany($mapping);
+            }
+        }
+
+        // Evaluate <many-to-one ...> mappings
+        if (isset($xmlRoot->{'many-to-one'})) {
+            foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) {
+                $mapping = array(
+                    'fieldName' => (string)$manyToOneElement['field'],
+                    'targetEntity' => (string)$manyToOneElement['target-entity']
+                );
+
+                if (isset($associationIds[$mapping['fieldName']])) {
+                    $mapping['id'] = true;
+                }
+
+                if (isset($manyToOneElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToOneElement['fetch']);
+                }
+
+                if (isset($manyToOneElement['inversed-by'])) {
+                    $mapping['inversedBy'] = (string)$manyToOneElement['inversed-by'];
+                }
+
+                $joinColumns = array();
+
+                if (isset($manyToOneElement->{'join-column'})) {
+                    $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'});
+                } else if (isset($manyToOneElement->{'join-columns'})) {
+                    foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
+                        $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+                }
+
+                $mapping['joinColumns'] = $joinColumns;
+
+                if (isset($manyToOneElement->cascade)) {
+                    $mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement->cascade);
+                }
+
+                $metadata->mapManyToOne($mapping);
+            }
+        }
+
+        // Evaluate <many-to-many ...> mappings
+        if (isset($xmlRoot->{'many-to-many'})) {
+            foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) {
+                $mapping = array(
+                    'fieldName' => (string)$manyToManyElement['field'],
+                    'targetEntity' => (string)$manyToManyElement['target-entity']
+                );
+
+                if (isset($manyToManyElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToManyElement['fetch']);
+                }
+
+                if (isset($manyToManyElement['orphan-removal'])) {
+                    $mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal'];
+                }
+
+                if (isset($manyToManyElement['mapped-by'])) {
+                    $mapping['mappedBy'] = (string)$manyToManyElement['mapped-by'];
+                } else if (isset($manyToManyElement->{'join-table'})) {
+                    if (isset($manyToManyElement['inversed-by'])) {
+                        $mapping['inversedBy'] = (string)$manyToManyElement['inversed-by'];
+                    }
+
+                    $joinTableElement = $manyToManyElement->{'join-table'};
+                    $joinTable = array(
+                        'name' => (string)$joinTableElement['name']
+                    );
+
+                    if (isset($joinTableElement['schema'])) {
+                        $joinTable['schema'] = (string)$joinTableElement['schema'];
+                    }
+
+                    foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
+                        $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+
+                    foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
+                        $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+
+                    $mapping['joinTable'] = $joinTable;
+                }
+
+                if (isset($manyToManyElement->cascade)) {
+                    $mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement->cascade);
+                }
+
+                if (isset($manyToManyElement->{'order-by'})) {
+                    $orderBy = array();
+                    foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
+                        $orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
+                    }
+                    $mapping['orderBy'] = $orderBy;
+                }
+
+                if (isset($manyToManyElement['index-by'])) {
+                    $mapping['indexBy'] = (string)$manyToManyElement['index-by'];
+                } else if (isset($manyToManyElement->{'index-by'})) {
+                    throw new \InvalidArgumentException("<index-by /> is not a valid tag");
+                }
+
+                $metadata->mapManyToMany($mapping);
+            }
+        }
+
+        // Evaluate <lifecycle-callbacks...>
+        if (isset($xmlRoot->{'lifecycle-callbacks'})) {
+            foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
+                $metadata->addLifecycleCallback((string)$lifecycleCallback['method'], constant('Doctrine\ORM\Events::' . (string)$lifecycleCallback['type']));
+            }
+        }
+    }
+
+    /**
+     * Constructs a joinColumn mapping array based on the information
+     * found in the given SimpleXMLElement.
+     *
+     * @param $joinColumnElement The XML element.
+     * @return array The mapping array.
+     */
+    private function _getJoinColumnMapping(SimpleXMLElement $joinColumnElement)
+    {
+        $joinColumn = array(
+            'name' => (string)$joinColumnElement['name'],
+            'referencedColumnName' => (string)$joinColumnElement['referenced-column-name']
+        );
+
+        if (isset($joinColumnElement['unique'])) {
+            $joinColumn['unique'] = ((string)$joinColumnElement['unique'] == "false") ? false : true;
+        }
+
+        if (isset($joinColumnElement['nullable'])) {
+            $joinColumn['nullable'] = ((string)$joinColumnElement['nullable'] == "false") ? false : true;
+        }
+
+        if (isset($joinColumnElement['on-delete'])) {
+            $joinColumn['onDelete'] = (string)$joinColumnElement['on-delete'];
+        }
+
+        if (isset($joinColumnElement['column-definition'])) {
+            $joinColumn['columnDefinition'] = (string)$joinColumnElement['column-definition'];
+        }
+
+        return $joinColumn;
+    }
+
+    /**
+     * Gathers a list of cascade options found in the given cascade element.
+     *
+     * @param $cascadeElement The cascade element.
+     * @return array The list of cascade options.
+     */
+    private function _getCascadeMappings($cascadeElement)
+    {
+        $cascades = array();
+        foreach ($cascadeElement->children() as $action) {
+            // According to the JPA specifications, XML uses "cascade-persist"
+            // instead of "persist". Here, both variations
+            // are supported because both YAML and Annotation use "persist"
+            // and we want to make sure that this driver doesn't need to know
+            // anything about the supported cascading actions
+            $cascades[] = str_replace('cascade-', '', $action->getName());
+        }
+        return $cascades;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _loadMappingFile($file)
+    {
+        $result = array();
+        $xmlElement = simplexml_load_file($file);
+
+        if (isset($xmlElement->entity)) {
+            foreach ($xmlElement->entity as $entityElement) {
+                $entityName = (string)$entityElement['name'];
+                $result[$entityName] = $entityElement;
+            }
+        } else if (isset($xmlElement->{'mapped-superclass'})) {
+            foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) {
+                $className = (string)$mappedSuperClass['name'];
+                $result[$className] = $mappedSuperClass;
+            }
+        }
+
+        return $result;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/YamlDriver.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/YamlDriver.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Driver/YamlDriver.php	(revision 345)
@@ -0,0 +1,512 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Mapping\MappingException;
+
+/**
+ * The YamlDriver reads the mapping metadata from yaml schema files.
+ *
+ * @since 2.0
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class YamlDriver extends AbstractFileDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $_fileExtension = '.dcm.yml';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
+    {
+        $element = $this->getElement($className);
+
+        if ($element['type'] == 'entity') {
+            if (isset($element['repositoryClass'])) {
+                $metadata->setCustomRepositoryClass($element['repositoryClass']);
+            }
+            if (isset($element['readOnly']) && $element['readOnly'] == true) {
+                $metadata->markReadOnly();
+            }
+        } else if ($element['type'] == 'mappedSuperclass') {
+            $metadata->setCustomRepositoryClass(
+                isset($element['repositoryClass']) ? $element['repositoryClass'] : null
+            );
+            $metadata->isMappedSuperclass = true;
+        } else {
+            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
+        }
+
+        // Evaluate root level properties
+        $table = array();
+        if (isset($element['table'])) {
+            $table['name'] = $element['table'];
+        }
+        $metadata->setPrimaryTable($table);
+
+        // Evaluate named queries
+        if (isset($element['namedQueries'])) {
+            foreach ($element['namedQueries'] as $name => $queryMapping) {
+                if (is_string($queryMapping)) {
+                    $queryMapping = array('query' => $queryMapping);
+                }
+
+                if ( ! isset($queryMapping['name'])) {
+                    $queryMapping['name'] = $name;
+                }
+
+                $metadata->addNamedQuery($queryMapping);
+            }
+        }
+
+        /* not implemented specially anyway. use table = schema.table
+        if (isset($element['schema'])) {
+            $metadata->table['schema'] = $element['schema'];
+        }*/
+
+        if (isset($element['inheritanceType'])) {
+            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
+
+            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
+                // Evaluate discriminatorColumn
+                if (isset($element['discriminatorColumn'])) {
+                    $discrColumn = $element['discriminatorColumn'];
+                    $metadata->setDiscriminatorColumn(array(
+                        'name' => $discrColumn['name'],
+                        'type' => $discrColumn['type'],
+                        'length' => $discrColumn['length']
+                    ));
+                } else {
+                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
+                }
+
+                // Evaluate discriminatorMap
+                if (isset($element['discriminatorMap'])) {
+                    $metadata->setDiscriminatorMap($element['discriminatorMap']);
+                }
+            }
+        }
+
+
+        // Evaluate changeTrackingPolicy
+        if (isset($element['changeTrackingPolicy'])) {
+            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
+                    . strtoupper($element['changeTrackingPolicy'])));
+        }
+
+        // Evaluate indexes
+        if (isset($element['indexes'])) {
+            foreach ($element['indexes'] as $name => $index) {
+                if ( ! isset($index['name'])) {
+                    $index['name'] = $name;
+                }
+
+                if (is_string($index['columns'])) {
+                    $columns = explode(',', $index['columns']);
+                } else {
+                    $columns = $index['columns'];
+                }
+
+                $metadata->table['indexes'][$index['name']] = array(
+                    'columns' => $columns
+                );
+            }
+        }
+
+        // Evaluate uniqueConstraints
+        if (isset($element['uniqueConstraints'])) {
+            foreach ($element['uniqueConstraints'] as $name => $unique) {
+                if ( ! isset($unique['name'])) {
+                    $unique['name'] = $name;
+                }
+
+                if (is_string($unique['columns'])) {
+                    $columns = explode(',', $unique['columns']);
+                } else {
+                    $columns = $unique['columns'];
+                }
+
+                $metadata->table['uniqueConstraints'][$unique['name']] = array(
+                    'columns' => $columns
+                );
+            }
+        }
+
+        $associationIds = array();
+        if (isset($element['id'])) {
+            // Evaluate identifier settings
+            foreach ($element['id'] as $name => $idElement) {
+                if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
+                    $associationIds[$name] = true;
+                    continue;
+                }
+
+                $mapping = array(
+                    'id' => true,
+                    'fieldName' => $name
+                );
+
+                if (isset($idElement['type'])) {
+                    $mapping['type'] = $idElement['type'];
+                }
+
+                if (isset($idElement['column'])) {
+                    $mapping['columnName'] = $idElement['column'];
+                }
+
+                if (isset($idElement['length'])) {
+                    $mapping['length'] = $idElement['length'];
+                }
+
+                if (isset($idElement['columnDefinition'])) {
+                    $mapping['columnDefinition'] = $idElement['columnDefinition'];
+                }
+
+                $metadata->mapField($mapping);
+
+                if (isset($idElement['generator'])) {
+                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
+                            . strtoupper($idElement['generator']['strategy'])));
+                }
+                // Check for SequenceGenerator/TableGenerator definition
+                if (isset($idElement['sequenceGenerator'])) {
+                    $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
+                } else if (isset($idElement['tableGenerator'])) {
+                    throw MappingException::tableIdGeneratorNotImplemented($className);
+                }
+            }
+        }
+
+        // Evaluate fields
+        if (isset($element['fields'])) {
+            foreach ($element['fields'] as $name => $fieldMapping) {
+
+                $mapping = array(
+                    'fieldName' => $name
+                );
+
+                if (isset($fieldMapping['type'])) {
+                    $e = explode('(', $fieldMapping['type']);
+                    $fieldMapping['type'] = $e[0];
+                    $mapping['type']      = $fieldMapping['type'];
+
+                    if (isset($e[1])) {
+                        $fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
+                    }
+                }
+
+                if (isset($fieldMapping['id'])) {
+                    $mapping['id'] = true;
+                    if (isset($fieldMapping['generator']['strategy'])) {
+                        $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
+                                . strtoupper($fieldMapping['generator']['strategy'])));
+                    }
+                }
+                if (isset($fieldMapping['column'])) {
+                    $mapping['columnName'] = $fieldMapping['column'];
+                }
+                if (isset($fieldMapping['length'])) {
+                    $mapping['length'] = $fieldMapping['length'];
+                }
+                if (isset($fieldMapping['precision'])) {
+                    $mapping['precision'] = $fieldMapping['precision'];
+                }
+                if (isset($fieldMapping['scale'])) {
+                    $mapping['scale'] = $fieldMapping['scale'];
+                }
+                if (isset($fieldMapping['unique'])) {
+                    $mapping['unique'] = (bool)$fieldMapping['unique'];
+                }
+                if (isset($fieldMapping['options'])) {
+                    $mapping['options'] = $fieldMapping['options'];
+                }
+                if (isset($fieldMapping['nullable'])) {
+                    $mapping['nullable'] = $fieldMapping['nullable'];
+                }
+                if (isset($fieldMapping['version']) && $fieldMapping['version']) {
+                    $metadata->setVersionMapping($mapping);
+                }
+                if (isset($fieldMapping['columnDefinition'])) {
+                    $mapping['columnDefinition'] = $fieldMapping['columnDefinition'];
+                }
+
+                $metadata->mapField($mapping);
+            }
+        }
+
+        // Evaluate oneToOne relationships
+        if (isset($element['oneToOne'])) {
+            foreach ($element['oneToOne'] as $name => $oneToOneElement) {
+                $mapping = array(
+                    'fieldName' => $name,
+                    'targetEntity' => $oneToOneElement['targetEntity']
+                );
+
+                if (isset($associationIds[$mapping['fieldName']])) {
+                    $mapping['id'] = true;
+                }
+
+                if (isset($oneToOneElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
+                }
+
+                if (isset($oneToOneElement['mappedBy'])) {
+                    $mapping['mappedBy'] = $oneToOneElement['mappedBy'];
+                } else {
+                    if (isset($oneToOneElement['inversedBy'])) {
+                        $mapping['inversedBy'] = $oneToOneElement['inversedBy'];
+                    }
+
+                    $joinColumns = array();
+
+                    if (isset($oneToOneElement['joinColumn'])) {
+                        $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']);
+                    } else if (isset($oneToOneElement['joinColumns'])) {
+                        foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) {
+                            if (!isset($joinColumnElement['name'])) {
+                                $joinColumnElement['name'] = $name;
+                            }
+
+                            $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
+                        }
+                    }
+
+                    $mapping['joinColumns'] = $joinColumns;
+                }
+
+                if (isset($oneToOneElement['cascade'])) {
+                    $mapping['cascade'] = $oneToOneElement['cascade'];
+                }
+
+                if (isset($oneToOneElement['orphanRemoval'])) {
+                    $mapping['orphanRemoval'] = (bool)$oneToOneElement['orphanRemoval'];
+                }
+
+                $metadata->mapOneToOne($mapping);
+            }
+        }
+
+        // Evaluate oneToMany relationships
+        if (isset($element['oneToMany'])) {
+            foreach ($element['oneToMany'] as $name => $oneToManyElement) {
+                $mapping = array(
+                    'fieldName' => $name,
+                    'targetEntity' => $oneToManyElement['targetEntity'],
+                    'mappedBy' => $oneToManyElement['mappedBy']
+                );
+
+                if (isset($oneToManyElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']);
+                }
+
+                if (isset($oneToManyElement['cascade'])) {
+                    $mapping['cascade'] = $oneToManyElement['cascade'];
+                }
+
+                if (isset($oneToManyElement['orphanRemoval'])) {
+                    $mapping['orphanRemoval'] = (bool)$oneToManyElement['orphanRemoval'];
+                }
+
+                if (isset($oneToManyElement['orderBy'])) {
+                    $mapping['orderBy'] = $oneToManyElement['orderBy'];
+                }
+
+                if (isset($oneToManyElement['indexBy'])) {
+                    $mapping['indexBy'] = $oneToManyElement['indexBy'];
+                }
+
+                $metadata->mapOneToMany($mapping);
+            }
+        }
+
+        // Evaluate manyToOne relationships
+        if (isset($element['manyToOne'])) {
+            foreach ($element['manyToOne'] as $name => $manyToOneElement) {
+                $mapping = array(
+                    'fieldName' => $name,
+                    'targetEntity' => $manyToOneElement['targetEntity']
+                );
+
+                if (isset($associationIds[$mapping['fieldName']])) {
+                    $mapping['id'] = true;
+                }
+
+                if (isset($manyToOneElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
+                }
+
+                if (isset($manyToOneElement['inversedBy'])) {
+                    $mapping['inversedBy'] = $manyToOneElement['inversedBy'];
+                }
+
+                $joinColumns = array();
+
+                if (isset($manyToOneElement['joinColumn'])) {
+                    $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']);
+                } else if (isset($manyToOneElement['joinColumns'])) {
+                    foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) {
+                        if (!isset($joinColumnElement['name'])) {
+                            $joinColumnElement['name'] = $name;
+                        }
+
+                        $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+                }
+
+                $mapping['joinColumns'] = $joinColumns;
+
+                if (isset($manyToOneElement['cascade'])) {
+                    $mapping['cascade'] = $manyToOneElement['cascade'];
+                }
+
+                $metadata->mapManyToOne($mapping);
+            }
+        }
+
+        // Evaluate manyToMany relationships
+        if (isset($element['manyToMany'])) {
+            foreach ($element['manyToMany'] as $name => $manyToManyElement) {
+                $mapping = array(
+                    'fieldName' => $name,
+                    'targetEntity' => $manyToManyElement['targetEntity']
+                );
+
+                if (isset($manyToManyElement['fetch'])) {
+                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']);
+                }
+
+                if (isset($manyToManyElement['mappedBy'])) {
+                    $mapping['mappedBy'] = $manyToManyElement['mappedBy'];
+                } else if (isset($manyToManyElement['joinTable'])) {
+
+                    $joinTableElement = $manyToManyElement['joinTable'];
+                    $joinTable = array(
+                        'name' => $joinTableElement['name']
+                    );
+
+                    if (isset($joinTableElement['schema'])) {
+                        $joinTable['schema'] = $joinTableElement['schema'];
+                    }
+
+                    foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
+                        if (!isset($joinColumnElement['name'])) {
+                            $joinColumnElement['name'] = $name;
+                        }
+
+                        $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+
+                    foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
+                        if (!isset($joinColumnElement['name'])) {
+                            $joinColumnElement['name'] = $name;
+                        }
+
+                        $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
+                    }
+
+                    $mapping['joinTable'] = $joinTable;
+                }
+
+                if (isset($manyToManyElement['inversedBy'])) {
+                    $mapping['inversedBy'] = $manyToManyElement['inversedBy'];
+                }
+
+                if (isset($manyToManyElement['cascade'])) {
+                    $mapping['cascade'] = $manyToManyElement['cascade'];
+                }
+
+                if (isset($manyToManyElement['orderBy'])) {
+                    $mapping['orderBy'] = $manyToManyElement['orderBy'];
+                }
+
+                if (isset($manyToManyElement['indexBy'])) {
+                    $mapping['indexBy'] = $manyToManyElement['indexBy'];
+                }
+
+                if (isset($manyToManyElement['orphanRemoval'])) {
+                    $mapping['orphanRemoval'] = (bool)$manyToManyElement['orphanRemoval'];
+                }
+
+                $metadata->mapManyToMany($mapping);
+            }
+        }
+
+        // Evaluate lifeCycleCallbacks
+        if (isset($element['lifecycleCallbacks'])) {
+            foreach ($element['lifecycleCallbacks'] as $type => $methods) {
+                foreach ($methods as $method) {
+                    $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type));
+                }
+            }
+        }
+    }
+
+    /**
+     * Constructs a joinColumn mapping array based on the information
+     * found in the given join column element.
+     *
+     * @param $joinColumnElement The array join column element
+     * @return array The mapping array.
+     */
+    private function _getJoinColumnMapping($joinColumnElement)
+    {
+        $joinColumn = array(
+            'name' => $joinColumnElement['name'],
+            'referencedColumnName' => $joinColumnElement['referencedColumnName']
+        );
+
+        if (isset($joinColumnElement['fieldName'])) {
+            $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
+        }
+
+        if (isset($joinColumnElement['unique'])) {
+            $joinColumn['unique'] = (bool) $joinColumnElement['unique'];
+        }
+
+        if (isset($joinColumnElement['nullable'])) {
+            $joinColumn['nullable'] = (bool) $joinColumnElement['nullable'];
+        }
+
+        if (isset($joinColumnElement['onDelete'])) {
+            $joinColumn['onDelete'] = $joinColumnElement['onDelete'];
+        }
+
+        if (isset($joinColumnElement['columnDefinition'])) {
+            $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
+        }
+
+        return $joinColumn;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _loadMappingFile($file)
+    {
+        return \Symfony\Component\Yaml\Yaml::parse($file);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ElementCollection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ElementCollection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ElementCollection.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("ALL")
+ * @todo check available targets
+ */
+final class ElementCollection implements Annotation
+{
+    /** @var string */
+    public $tableName;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Entity.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Entity.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Entity.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class Entity implements Annotation
+{
+    /** @var string */
+    public $repositoryClass;
+    /** @var boolean */
+    public $readOnly = false;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/GeneratedValue.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/GeneratedValue.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/GeneratedValue.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class GeneratedValue implements Annotation
+{
+     /** @var string */
+    public $strategy = 'AUTO';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class HasLifecycleCallbacks implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Id.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Id.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Id.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class Id implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Index.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Index.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Index.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("ANNOTATION")
+ */
+final class Index implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var array<string> */
+    public $columns;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/InheritanceType.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/InheritanceType.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/InheritanceType.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class InheritanceType implements Annotation
+{
+    /** @var string */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumn.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumn.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumn.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY","ANNOTATION"})
+ */
+final class JoinColumn implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var string */
+    public $referencedColumnName = 'id';
+    /** @var boolean */
+    public $unique = false;
+    /** @var boolean */
+    public $nullable = true;
+    /** @var mixed */
+    public $onDelete;
+    /** @var string */
+    public $columnDefinition;
+    /** @var string */
+    public $fieldName; // field name used in non-object hydration (array/scalar)
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumns.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumns.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinColumns.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class JoinColumns implements Annotation
+{
+    /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinTable.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinTable.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/JoinTable.php	(revision 345)
@@ -0,0 +1,36 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class JoinTable implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var string */
+    public $schema;
+    /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
+    public $joinColumns = array();
+    /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
+    public $inverseJoinColumns = array();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToMany.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToMany.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToMany.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class ManyToMany implements Annotation
+{
+    /** @var string */
+    public $targetEntity;
+    /** @var string */
+    public $mappedBy;
+    /** @var string */
+    public $inversedBy;
+    /** @var array<string> */
+    public $cascade;
+    /** @var string */
+    public $fetch = 'LAZY';
+    /** @var boolean */
+    public $orphanRemoval = false;
+    /** @var string */
+    public $indexBy;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToOne.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToOne.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/ManyToOne.php	(revision 345)
@@ -0,0 +1,36 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class ManyToOne implements Annotation
+{
+    /** @var string */
+    public $targetEntity;
+    /** @var array<string> */
+    public $cascade;
+    /** @var string */
+    public $fetch = 'LAZY';
+    /** @var string */
+    public $inversedBy;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappedSuperclass.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappedSuperclass.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappedSuperclass.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class MappedSuperclass implements Annotation
+{
+    /** @var string */
+    public $repositoryClass;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappingException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappingException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/MappingException.php	(revision 345)
@@ -0,0 +1,332 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * A MappingException indicates that something is wrong with the mapping setup.
+ *
+ * @since 2.0
+ */
+class MappingException extends \Doctrine\ORM\ORMException
+{
+    public static function pathRequired()
+    {
+        return new self("Specifying the paths to your entities is required ".
+            "in the AnnotationDriver to retrieve all class names.");
+    }
+
+    public static function identifierRequired($entityName)
+    {
+        return new self("No identifier/primary key specified for Entity '$entityName'."
+                . " Every Entity must have an identifier/primary key.");
+    }
+
+    public static function invalidInheritanceType($entityName, $type)
+    {
+        return new self("The inheritance type '$type' specified for '$entityName' does not exist.");
+    }
+
+    public static function generatorNotAllowedWithCompositeId()
+    {
+        return new self("Id generators can't be used with a composite id.");
+    }
+
+    public static function missingFieldName($entity)
+    {
+        return new self("The field or association mapping misses the 'fieldName' attribute in entity '$entity'.");
+    }
+
+    public static function missingTargetEntity($fieldName)
+    {
+        return new self("The association mapping '$fieldName' misses the 'targetEntity' attribute.");
+    }
+
+    public static function missingSourceEntity($fieldName)
+    {
+        return new self("The association mapping '$fieldName' misses the 'sourceEntity' attribute.");
+    }
+
+    public static function mappingFileNotFound($entityName, $fileName)
+    {
+        return new self("No mapping file found named '$fileName' for class '$entityName'.");
+    }
+
+    public static function invalidMappingFile($entityName, $fileName)
+    {
+        return new self("Invalid mapping file '$fileName' for class '$entityName'.");
+    }
+
+    public static function mappingNotFound($className, $fieldName)
+    {
+        return new self("No mapping found for field '$fieldName' on class '$className'.");
+    }
+
+    public static function queryNotFound($className, $queryName)
+    {
+        return new self("No query found named '$queryName' on class '$className'.");
+    }
+
+    public static function oneToManyRequiresMappedBy($fieldName)
+    {
+        return new self("OneToMany mapping on field '$fieldName' requires the 'mappedBy' attribute.");
+    }
+
+    public static function joinTableRequired($fieldName)
+    {
+        return new self("The mapping of field '$fieldName' requires an the 'joinTable' attribute.");
+    }
+
+    /**
+     * Called if a required option was not found but is required
+     *
+     * @param string $field which field cannot be processed?
+     * @param string $expectedOption which option is required
+     * @param string $hint  Can optionally be used to supply a tip for common mistakes,
+     *                      e.g. "Did you think of the plural s?"
+     * @return MappingException
+     */
+    static function missingRequiredOption($field, $expectedOption, $hint = '')
+    {
+        $message = "The mapping of field '{$field}' is invalid: The option '{$expectedOption}' is required.";
+
+        if ( ! empty($hint)) {
+            $message .= ' (Hint: ' . $hint . ')';
+        }
+
+        return new self($message);
+    }
+
+    /**
+     * Generic exception for invalid mappings.
+     *
+     * @param string $fieldName
+     */
+    public static function invalidMapping($fieldName)
+    {
+        return new self("The mapping of field '$fieldName' is invalid.");
+    }
+
+    /**
+     * Exception for reflection exceptions - adds the entity name,
+     * because there might be long classnames that will be shortened
+     * within the stacktrace
+     *
+     * @param string $entity The entity's name
+     * @param \ReflectionException $previousException
+     */
+    public static function reflectionFailure($entity, \ReflectionException $previousException)
+    {
+        return new self('An error occurred in ' . $entity, 0, $previousException);
+    }
+
+    public static function joinColumnMustPointToMappedField($className, $joinColumn)
+    {
+        return new self('The column ' . $joinColumn . ' must be mapped to a field in class '
+                . $className . ' since it is referenced by a join column of another class.');
+    }
+
+    public static function classIsNotAValidEntityOrMappedSuperClass($className)
+    {
+        return new self('Class '.$className.' is not a valid entity or mapped super class.');
+    }
+
+    public static function propertyTypeIsRequired($className, $propertyName)
+    {
+        return new self("The attribute 'type' is required for the column description of property ".$className."::\$".$propertyName.".");
+    }
+
+    public static function tableIdGeneratorNotImplemented($className)
+    {
+        return new self("TableIdGenerator is not yet implemented for use with class ".$className);
+    }
+
+    /**
+     *
+     * @param string $entity The entity's name
+     * @param string $fieldName The name of the field that was already declared
+     */
+    public static function duplicateFieldMapping($entity, $fieldName) {
+        return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
+    }
+
+    public static function duplicateAssociationMapping($entity, $fieldName) {
+        return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
+    }
+
+    public static function duplicateQueryMapping($entity, $queryName) {
+        return new self('Query named "'.$queryName.'" in "'.$entity.'" was already declared, but it must be declared only once');
+    }
+
+    public static function singleIdNotAllowedOnCompositePrimaryKey($entity) {
+        return new self('Single id is not allowed on composite primary key in entity '.$entity);
+    }
+
+    public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType) {
+        return new self('Locking type "'.$unsupportedType.'" (specified in "'.$entity.'", field "'.$fieldName.'") '
+                        .'is not supported by Doctrine.'
+        );
+    }
+
+    public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null)
+    {
+        if ( ! empty($path)) {
+            $path = '[' . $path . ']';
+        }
+
+        return new self(
+            'File mapping drivers must have a valid directory path, ' .
+            'however the given path ' . $path . ' seems to be incorrect!'
+        );
+    }
+
+    /**
+     * Throws an exception that indicates that a class used in a discriminator map does not exist.
+     * An example would be an outdated (maybe renamed) classname.
+     *
+     * @param string $className The class that could not be found
+     * @param string $owningClass The class that declares the discriminator map.
+     * @return self
+     */
+    public static function invalidClassInDiscriminatorMap($className, $owningClass) {
+        return new self(
+            "Entity class '$className' used in the discriminator map of class '$owningClass' ".
+            "does not exist."
+        );
+    }
+
+    public static function missingDiscriminatorMap($className)
+    {
+        return new self("Entity class '$className' is using inheritance but no discriminator map was defined.");
+    }
+
+    public static function missingDiscriminatorColumn($className)
+    {
+        return new self("Entity class '$className' is using inheritance but no discriminator column was defined.");
+    }
+
+    public static function invalidDiscriminatorColumnType($className, $type)
+    {
+        return new self("Discriminator column type on entity class '$className' is not allowed to be '$type'. 'string' or 'integer' type variables are suggested!");
+    }
+
+    public static function cannotVersionIdField($className, $fieldName)
+    {
+        return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported.");
+    }
+
+    public static function sqlConversionNotAllowedForIdentifiers($className, $fieldName, $type)
+    {
+        return new self("It is not possible to set id field '$fieldName' to type '$type' in entity class '$className'. The type '$type' requires conversion SQL which is not allowed for identifiers.");
+    }
+
+    /**
+     * @param  string $className
+     * @param  string $columnName
+     * @return self
+     */
+    public static function duplicateColumnName($className, $columnName)
+    {
+        return new self("Duplicate definition of column '".$columnName."' on entity '".$className."' in a field or discriminator column mapping.");
+    }
+
+    public static function illegalToManyAssocationOnMappedSuperclass($className, $field)
+    {
+        return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'.");
+    }
+
+    /**
+     * @param string $className
+     * @param string $targetEntity
+     * @param string $targetField
+     * @return self
+     */
+    public static function cannotMapCompositePrimaryKeyEntitiesAsForeignId($className, $targetEntity, $targetField)
+    {
+        return new self("It is not possible to map entity '".$className."' with a composite primary key ".
+            "as part of the primary key of another entity '".$targetEntity."#".$targetField."'.");
+    }
+
+    public static function noSingleAssociationJoinColumnFound($className, $field)
+    {
+        return new self("'$className#$field' is not an association with a single join column.");
+    }
+
+    public static function noFieldNameFoundForColumn($className, $column)
+    {
+        return new self("Cannot find a field on '$className' that is mapped to column '$column'. Either the ".
+            "field does not exist or an association exists but it has multiple join columns.");
+    }
+
+    public static function illegalOrphanRemovalOnIdentifierAssociation($className, $field)
+    {
+        return new self("The orphan removal option is not allowed on an association that is ".
+            "part of the identifier in '$className#$field'.");
+    }
+
+    public static function illegalOrphanRemoval($className, $field)
+    {
+        return new self("Orphan removal is only allowed on one-to-one and one-to-many ".
+                "associations, but " . $className."#" .$field . " is not.");
+    }
+
+    public static function illegalInverseIdentifierAssocation($className, $field)
+    {
+        return new self("An inverse association is not allowed to be identifier in '$className#$field'.");
+    }
+
+    public static function illegalToManyIdentifierAssoaction($className, $field)
+    {
+        return new self("Many-to-many or one-to-many associations are not allowed to be identifier in '$className#$field'.");
+    }
+
+    public static function noInheritanceOnMappedSuperClass($className)
+    {
+        return new self("Its not supported to define inheritance information on a mapped superclass '" . $className . "'.");
+    }
+
+    public static function mappedClassNotPartOfDiscriminatorMap($className, $rootClassName)
+    {
+        return new self(
+            "Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " .
+            "to be properly mapped in the inheritance hierachy. Alternatively you can make '".$className."' an abstract class " .
+            "to avoid this exception from occuring."
+        );
+    }
+
+    public static function lifecycleCallbackMethodNotFound($className, $methodName)
+    {
+        return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback.");
+    }
+
+    public static function invalidFetchMode($className, $annotation)
+    {
+        return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $annotation . "'");
+    }
+
+    public static function compositeKeyAssignedIdGeneratorRequired($className)
+    {
+        return new self("Entity '". $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported.");
+    }
+
+    public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName)
+    {
+        return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQueries.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQueries.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQueries.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class NamedQueries implements Annotation
+{
+    /** @var array<\Doctrine\ORM\Mapping\NamedQuery> */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQuery.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQuery.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/NamedQuery.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("ANNOTATION")
+ */
+final class NamedQuery implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var string */
+    public $query;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToMany.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToMany.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToMany.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class OneToMany implements Annotation
+{
+    /** @var string */
+    public $mappedBy;
+    /** @var string */
+    public $targetEntity;
+    /** @var array<string> */
+    public $cascade;
+    /** @var string */
+    public $fetch = 'LAZY';
+    /** @var boolean */
+    public $orphanRemoval = false;
+    /** @var string */
+    public $indexBy;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToOne.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToOne.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OneToOne.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class OneToOne implements Annotation
+{
+    /** @var string */
+    public $targetEntity;
+    /** @var string */
+    public $mappedBy;
+    /** @var string */
+    public $inversedBy;
+    /** @var array<string> */
+    public $cascade;
+    /** @var string */
+    public $fetch = 'LAZY';
+    /** @var boolean */
+    public $orphanRemoval = false;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OrderBy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OrderBy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/OrderBy.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class OrderBy implements Annotation
+{
+    /** @var array<string> */
+    public $value;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostLoad.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostLoad.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostLoad.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PostLoad implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostPersist.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostPersist.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostPersist.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PostPersist implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostRemove.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostRemove.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostRemove.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PostRemove implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostUpdate.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostUpdate.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PostUpdate.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PostUpdate implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreFlush.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreFlush.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreFlush.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PreFlush implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PrePersist.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PrePersist.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PrePersist.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PrePersist implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreRemove.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreRemove.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreRemove.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PreRemove implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreUpdate.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreUpdate.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/PreUpdate.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("METHOD")
+ */
+final class PreUpdate implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/SequenceGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/SequenceGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/SequenceGenerator.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class SequenceGenerator implements Annotation
+{
+    /** @var string */
+    public $sequenceName;
+    /** @var integer */
+    public $allocationSize = 1;
+    /** @var integer */
+    public $initialValue = 1;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Table.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Table.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Table.php	(revision 345)
@@ -0,0 +1,36 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class Table implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var string */
+    public $schema;
+    /** @var array<\Doctrine\ORM\Mapping\Index> */
+    public $indexes;
+    /** @var array<\Doctrine\ORM\Mapping\UniqueConstraint> */
+    public $uniqueConstraints;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/UniqueConstraint.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/UniqueConstraint.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/UniqueConstraint.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("ANNOTATION")
+ */
+final class UniqueConstraint implements Annotation
+{
+    /** @var string */
+    public $name;
+    /** @var array<string> */
+    public $columns;
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Version.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Version.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Mapping/Version.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class Version implements Annotation
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NativeQuery.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NativeQuery.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NativeQuery.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Represents a native SQL query.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+final class NativeQuery extends AbstractQuery
+{
+    private $_sql;
+
+    /**
+     * Sets the SQL of the query.
+     *
+     * @param string $sql
+     * @return NativeQuery This query instance.
+     */
+    public function setSQL($sql)
+    {
+        $this->_sql = $sql;
+
+        return $this;
+    }
+
+    /**
+     * Gets the SQL query.
+     *
+     * @return mixed The built SQL query or an array of all SQL queries.
+     * @override
+     */
+    public function getSQL()
+    {
+        return $this->_sql;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _doExecute()
+    {
+        $params = $this->_params;
+        $types  = $this->_paramTypes;
+
+        if ($params && is_int(key($params))) {
+            ksort($params);
+            ksort($types);
+
+            $params = array_values($params);
+            $types  = array_values($types);
+        }
+
+        return $this->_em->getConnection()->executeQuery(
+            $this->_sql, $params, $types, $this->_queryCacheProfile
+        );
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NoResultException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NoResultException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NoResultException.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Exception thrown when an ORM query unexpectedly does not return any results.
+ *
+ * @author robo
+ * @since 2.0
+ */
+class NoResultException extends ORMException
+{
+    public function __construct()
+    {
+        parent::__construct('No result was found for query although at least one row was expected.');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NonUniqueResultException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NonUniqueResultException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/NonUniqueResultException.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Exception thrown when an ORM query unexpectedly returns more than one result.
+ *
+ * @author robo
+ * @since 2.0
+ */
+class NonUniqueResultException extends ORMException {}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMException.php	(revision 345)
@@ -0,0 +1,152 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Exception;
+
+/**
+ * Base exception class for all ORM exceptions.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class ORMException extends Exception
+{
+    public static function missingMappingDriverImpl()
+    {
+        return new self("It's a requirement to specify a Metadata Driver and pass it ".
+            "to Doctrine\ORM\Configuration::setMetadataDriverImpl().");
+    }
+
+    public static function entityMissingForeignAssignedId($entity, $relatedEntity)
+    {
+        return new self(
+            "Entity of type " . get_class($entity) . " has identity through a foreign entity " . get_class($relatedEntity) . ", " .
+            "however this entity has no identity itself. You have to call EntityManager#persist() on the related entity " .
+            "and make sure that an identifier was generated before trying to persist '" . get_class($entity) . "'. In case " .
+            "of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call " .
+            "EntityManager#flush() between both persist operations."
+        );
+    }
+
+    public static function entityMissingAssignedIdForField($entity, $field)
+    {
+        return new self("Entity of type " . get_class($entity) . " is missing an assigned ID for field  '" . $field . "'. " .
+            "The identifier generation strategy for this entity requires the ID field to be populated before ".
+            "EntityManager#persist() is called. If you want automatically generated identifiers instead " .
+            "you need to adjust the metadata mapping accordingly."
+        );
+    }
+    public static function unrecognizedField($field)
+    {
+        return new self("Unrecognized field: $field");
+    }
+
+    /**
+     * @param string $className
+     * @param string $field
+     */
+    public static function invalidOrientation($className, $field)
+    {
+        return new self("Invalid order by orientation specified for " . $className . "#" . $field);
+    }
+
+    public static function invalidFlushMode($mode)
+    {
+        return new self("'$mode' is an invalid flush mode.");
+    }
+
+    public static function entityManagerClosed()
+    {
+        return new self("The EntityManager is closed.");
+    }
+
+    public static function invalidHydrationMode($mode)
+    {
+        return new self("'$mode' is an invalid hydration mode.");
+    }
+
+    public static function mismatchedEventManager()
+    {
+        return new self("Cannot use different EventManager instances for EntityManager and Connection.");
+    }
+
+    public static function findByRequiresParameter($methodName)
+    {
+        return new self("You need to pass a parameter to '".$methodName."'");
+    }
+
+    public static function invalidFindByCall($entityName, $fieldName, $method)
+    {
+        return new self(
+            "Entity '".$entityName."' has no field '".$fieldName."'. ".
+            "You can therefore not call '".$method."' on the entities' repository"
+        );
+    }
+
+    public static function invalidFindByInverseAssociation($entityName, $associationFieldName)
+    {
+        return new self(
+            "You cannot search for the association field '".$entityName."#".$associationFieldName."', ".
+            "because it is the inverse side of an association. Find methods only work on owning side associations."
+        );
+    }
+
+    public static function invalidResultCacheDriver() {
+        return new self("Invalid result cache driver; it must implement \Doctrine\Common\Cache\Cache.");
+    }
+
+    public static function notSupported() {
+        return new self("This behaviour is (currently) not supported by Doctrine 2");
+    }
+
+    public static function queryCacheNotConfigured()
+    {
+        return new self('Query Cache is not configured.');
+    }
+
+    public static function metadataCacheNotConfigured()
+    {
+        return new self('Class Metadata Cache is not configured.');
+    }
+
+    public static function proxyClassesAlwaysRegenerating()
+    {
+        return new self('Proxy Classes are always regenerating.');
+    }
+
+    public static function unknownEntityNamespace($entityNamespaceAlias)
+    {
+        return new self(
+            "Unknown Entity namespace alias '$entityNamespaceAlias'."
+        );
+    }
+
+    public static function invalidEntityRepository($className)
+    {
+        return new self("Invalid repository class '".$className."'. ".
+                "it must be a Doctrine\ORM\EntityRepository.");
+    }
+
+    public static function missingIdentifierField($className, $fieldName)
+    {
+        return new self("The identifier $fieldName is missing for a query of " . $className);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMInvalidArgumentException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMInvalidArgumentException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/ORMInvalidArgumentException.php	(revision 345)
@@ -0,0 +1,107 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ORMInvalidArgumentException extends \InvalidArgumentException
+{
+    static public function scheduleInsertForManagedEntity($entity)
+    {
+        return new self("A managed+dirty entity " . self::objToStr($entity) . " can not be scheduled for insertion.");
+    }
+
+    static public function scheduleInsertForRemovedEntity($entity)
+    {
+        return new self("Removed entity " . self::objToStr($entity) . " can not be scheduled for insertion.");
+    }
+
+    static public function scheduleInsertTwice($entity)
+    {
+        return new self("Entity " . self::objToStr($entity) . " can not be scheduled for insertion twice.");
+    }
+
+    static public function entityWithoutIdentity($className, $entity)
+    {
+        throw new self(
+            "The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " . 
+            "id values set. It cannot be added to the identity map."
+        );
+    }
+
+    static public function readOnlyRequiresManagedEntity($entity)
+    {
+        return new self("Only managed entities can be marked or checked as read only. But " . self::objToStr($entity) . " is not");
+    }
+
+    static public function newEntityFoundThroughRelationship(array $assoc, $entry)
+    {
+        return new self("A new entity was found through the relationship '"
+                            . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' that was not"
+                            . " configured to cascade persist operations for entity: " . self::objToStr($entry) . "."
+                            . " To solve this issue: Either explicitly call EntityManager#persist()"
+                            . " on this unknown entity or configure cascade persist "
+                            . " this association in the mapping for example @ManyToOne(..,cascade={\"persist\"}). "
+                            . " If you cannot find out which entity causes the problem"
+                            . " implement '" . $assoc['targetEntity'] . "#__toString()' to get a clue.");
+    }
+
+    static public function detachedEntityFoundThroughRelationship(array $assoc, $entry)
+    {
+        throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
+                        . " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' "
+                        . "during cascading a persist operation.");
+    }
+
+    static public function entityNotManaged($entity)
+    {
+        throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
+                "from the database or registered as new through EntityManager#persist");
+    }
+
+    static public function entityHasNoIdentity($entity, $operation)
+    {
+        throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
+    }
+
+    static public function entityIsRemoved($entity, $operation)
+    {
+        throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
+    }
+
+    static public function detachedEntityCannot($entity, $operation)
+    {
+        throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
+    }
+
+    /**
+     * Helper method to show an object as string.
+     *
+     * @param  object $obj
+     * @return string
+     */
+    private static function objToStr($obj)
+    {
+        return method_exists($obj, '__toString') ? (string)$obj : get_class($obj).'@'.spl_object_hash($obj);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/OptimisticLockException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/OptimisticLockException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/OptimisticLockException.php	(revision 345)
@@ -0,0 +1,64 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * An OptimisticLockException is thrown when a version check on an object
+ * that uses optimistic locking through a version field fails.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.0
+ */
+class OptimisticLockException extends ORMException
+{
+    private $entity;
+
+    public function __construct($msg, $entity)
+    {
+        parent::__construct($msg);
+        $this->entity = $entity;
+    }
+
+    /**
+     * Gets the entity that caused the exception.
+     *
+     * @return object
+     */
+    public function getEntity()
+    {
+        return $this->entity;
+    }
+
+    public static function lockFailed($entity)
+    {
+        return new self("The optimistic lock on an entity failed.", $entity);
+    }
+
+    public static function lockFailedVersionMissmatch($entity, $expectedLockVersion, $actualLockVersion)
+    {
+        return new self("The optimistic lock failed, version " . $expectedLockVersion . " was expected, but is actually ".$actualLockVersion, $entity);
+    }
+
+    public static function notVersioned($entityName)
+    {
+        return new self("Cannot obtain optimistic lock on unversioned entity " . $entityName, null);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PersistentCollection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PersistentCollection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PersistentCollection.php	(revision 345)
@@ -0,0 +1,792 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\Common\Collections\Collection,
+    Doctrine\Common\Collections\ArrayCollection,
+    Closure;
+
+/**
+ * A PersistentCollection represents a collection of elements that have persistent state.
+ *
+ * Collections of entities represent only the associations (links) to those entities.
+ * That means, if the collection is part of a many-many mapping and you remove
+ * entities from the collection, only the links in the relation table are removed (on flush).
+ * Similarly, if you remove entities from a collection that is part of a one-many
+ * mapping this will only result in the nulling out of the foreign keys on flush.
+ *
+ * @since     2.0
+ * @author    Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author    Roman Borschel <roman@code-factory.org>
+ * @author    Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ * @todo Design for inheritance to allow custom implementations?
+ */
+final class PersistentCollection implements Collection
+{
+    /**
+     * A snapshot of the collection at the moment it was fetched from the database.
+     * This is used to create a diff of the collection at commit time.
+     *
+     * @var array
+     */
+    private $snapshot = array();
+
+    /**
+     * The entity that owns this collection.
+     *
+     * @var object
+     */
+    private $owner;
+
+    /**
+     * The association mapping the collection belongs to.
+     * This is currently either a OneToManyMapping or a ManyToManyMapping.
+     *
+     * @var array
+     */
+    private $association;
+
+    /**
+     * The EntityManager that manages the persistence of the collection.
+     *
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * The name of the field on the target entities that points to the owner
+     * of the collection. This is only set if the association is bi-directional.
+     *
+     * @var string
+     */
+    private $backRefFieldName;
+
+    /**
+     * The class descriptor of the collection's entity type.
+     */
+    private $typeClass;
+
+    /**
+     * Whether the collection is dirty and needs to be synchronized with the database
+     * when the UnitOfWork that manages its persistent state commits.
+     *
+     * @var boolean
+     */
+    private $isDirty = false;
+
+    /**
+     * Whether the collection has already been initialized.
+     *
+     * @var boolean
+     */
+    private $initialized = true;
+
+    /**
+     * The wrapped Collection instance.
+     *
+     * @var Collection
+     */
+    private $coll;
+
+    /**
+     * Creates a new persistent collection.
+     *
+     * @param EntityManager $em The EntityManager the collection will be associated with.
+     * @param ClassMetadata $class The class descriptor of the entity type of this collection.
+     * @param array The collection elements.
+     */
+    public function __construct(EntityManager $em, $class, $coll)
+    {
+        $this->coll      = $coll;
+        $this->em        = $em;
+        $this->typeClass = $class;
+    }
+
+    /**
+     * INTERNAL:
+     * Sets the collection's owning entity together with the AssociationMapping that
+     * describes the association between the owner and the elements of the collection.
+     *
+     * @param object $entity
+     * @param AssociationMapping $assoc
+     */
+    public function setOwner($entity, array $assoc)
+    {
+        $this->owner            = $entity;
+        $this->association      = $assoc;
+        $this->backRefFieldName = $assoc['inversedBy'] ?: $assoc['mappedBy'];
+    }
+
+    /**
+     * INTERNAL:
+     * Gets the collection owner.
+     *
+     * @return object
+     */
+    public function getOwner()
+    {
+        return $this->owner;
+    }
+
+    public function getTypeClass()
+    {
+        return $this->typeClass;
+    }
+
+    /**
+     * INTERNAL:
+     * Adds an element to a collection during hydration. This will automatically
+     * complete bidirectional associations in the case of a one-to-many association.
+     *
+     * @param mixed $element The element to add.
+     */
+    public function hydrateAdd($element)
+    {
+        $this->coll->add($element);
+
+        // If _backRefFieldName is set and its a one-to-many association,
+        // we need to set the back reference.
+        if ($this->backRefFieldName && $this->association['type'] === ClassMetadata::ONE_TO_MANY) {
+            // Set back reference to owner
+            $this->typeClass->reflFields[$this->backRefFieldName]->setValue(
+                $element, $this->owner
+            );
+
+            $this->em->getUnitOfWork()->setOriginalEntityProperty(
+                spl_object_hash($element), $this->backRefFieldName, $this->owner
+            );
+        }
+    }
+
+    /**
+     * INTERNAL:
+     * Sets a keyed element in the collection during hydration.
+     *
+     * @param mixed $key The key to set.
+     * $param mixed $value The element to set.
+     */
+    public function hydrateSet($key, $element)
+    {
+        $this->coll->set($key, $element);
+
+        // If _backRefFieldName is set, then the association is bidirectional
+        // and we need to set the back reference.
+        if ($this->backRefFieldName && $this->association['type'] === ClassMetadata::ONE_TO_MANY) {
+            // Set back reference to owner
+            $this->typeClass->reflFields[$this->backRefFieldName]->setValue(
+                $element, $this->owner
+            );
+        }
+    }
+
+    /**
+     * Initializes the collection by loading its contents from the database
+     * if the collection is not yet initialized.
+     */
+    public function initialize()
+    {
+        if ($this->initialized || ! $this->association) {
+            return;
+        }
+
+        // Has NEW objects added through add(). Remember them.
+        $newObjects = array();
+
+        if ($this->isDirty) {
+            $newObjects = $this->coll->toArray();
+        }
+
+        $this->coll->clear();
+        $this->em->getUnitOfWork()->loadCollection($this);
+        $this->takeSnapshot();
+
+        // Reattach NEW objects added through add(), if any.
+        if ($newObjects) {
+            foreach ($newObjects as $obj) {
+                $this->coll->add($obj);
+            }
+
+            $this->isDirty = true;
+        }
+
+        $this->initialized = true;
+    }
+
+    /**
+     * INTERNAL:
+     * Tells this collection to take a snapshot of its current state.
+     */
+    public function takeSnapshot()
+    {
+        $this->snapshot = $this->coll->toArray();
+        $this->isDirty  = false;
+    }
+
+    /**
+     * INTERNAL:
+     * Returns the last snapshot of the elements in the collection.
+     *
+     * @return array The last snapshot of the elements.
+     */
+    public function getSnapshot()
+    {
+        return $this->snapshot;
+    }
+
+    /**
+     * INTERNAL:
+     * getDeleteDiff
+     *
+     * @return array
+     */
+    public function getDeleteDiff()
+    {
+        return array_udiff_assoc(
+            $this->snapshot,
+            $this->coll->toArray(),
+            function($a, $b) { return $a === $b ? 0 : 1; }
+        );
+    }
+
+    /**
+     * INTERNAL:
+     * getInsertDiff
+     *
+     * @return array
+     */
+    public function getInsertDiff()
+    {
+        return array_udiff_assoc(
+            $this->coll->toArray(),
+            $this->snapshot,
+            function($a, $b) { return $a === $b ? 0 : 1; }
+        );
+    }
+
+    /**
+     * INTERNAL: Gets the association mapping of the collection.
+     *
+     * @return array
+     */
+    public function getMapping()
+    {
+        return $this->association;
+    }
+
+    /**
+     * Marks this collection as changed/dirty.
+     */
+    private function changed()
+    {
+        if ($this->isDirty) {
+            return;
+        }
+
+        $this->isDirty = true;
+
+        if ($this->association !== null &&
+            $this->association['isOwningSide'] &&
+            $this->association['type'] === ClassMetadata::MANY_TO_MANY &&
+            $this->owner &&
+            $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) {
+            $this->em->getUnitOfWork()->scheduleForDirtyCheck($this->owner);
+        }
+    }
+
+    /**
+     * Gets a boolean flag indicating whether this collection is dirty which means
+     * its state needs to be synchronized with the database.
+     *
+     * @return boolean TRUE if the collection is dirty, FALSE otherwise.
+     */
+    public function isDirty()
+    {
+        return $this->isDirty;
+    }
+
+    /**
+     * Sets a boolean flag, indicating whether this collection is dirty.
+     *
+     * @param boolean $dirty Whether the collection should be marked dirty or not.
+     */
+    public function setDirty($dirty)
+    {
+        $this->isDirty = $dirty;
+    }
+
+    /**
+     * Sets the initialized flag of the collection, forcing it into that state.
+     *
+     * @param boolean $bool
+     */
+    public function setInitialized($bool)
+    {
+        $this->initialized = $bool;
+    }
+
+    /**
+     * Checks whether this collection has been initialized.
+     *
+     * @return boolean
+     */
+    public function isInitialized()
+    {
+        return $this->initialized;
+    }
+
+    /** {@inheritdoc} */
+    public function first()
+    {
+        $this->initialize();
+
+        return $this->coll->first();
+    }
+
+    /** {@inheritdoc} */
+    public function last()
+    {
+        $this->initialize();
+
+        return $this->coll->last();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function remove($key)
+    {
+        // TODO: If the keys are persistent as well (not yet implemented)
+        //       and the collection is not initialized and orphanRemoval is
+        //       not used we can issue a straight SQL delete/update on the
+        //       association (table). Without initializing the collection.
+        $this->initialize();
+
+        $removed = $this->coll->remove($key);
+
+        if ( ! $removed) {
+            return $removed;
+        }
+
+        $this->changed();
+
+        if ($this->association !== null &&
+            $this->association['type'] & ClassMetadata::TO_MANY &&
+            $this->owner &&
+            $this->association['orphanRemoval']) {
+            $this->em->getUnitOfWork()->scheduleOrphanRemoval($removed);
+        }
+
+        return $removed;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function removeElement($element)
+    {
+        if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) {
+            if ($this->coll->contains($element)) {
+                return $this->coll->removeElement($element);
+            }
+
+            $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
+
+            if ($persister->removeElement($this, $element)) {
+                return $element;
+            }
+
+            return null;
+        }
+
+        $this->initialize();
+
+        $removed = $this->coll->removeElement($element);
+
+        if ( ! $removed) {
+            return $removed;
+        }
+
+        $this->changed();
+
+        if ($this->association !== null &&
+            $this->association['type'] & ClassMetadata::TO_MANY &&
+            $this->owner &&
+            $this->association['orphanRemoval']) {
+            $this->em->getUnitOfWork()->scheduleOrphanRemoval($element);
+        }
+
+        return $removed;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function containsKey($key)
+    {
+        $this->initialize();
+
+        return $this->coll->containsKey($key);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function contains($element)
+    {
+        if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) {
+            $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
+
+            return $this->coll->contains($element) || $persister->contains($this, $element);
+        }
+
+        $this->initialize();
+
+        return $this->coll->contains($element);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function exists(Closure $p)
+    {
+        $this->initialize();
+
+        return $this->coll->exists($p);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function indexOf($element)
+    {
+        $this->initialize();
+
+        return $this->coll->indexOf($element);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key)
+    {
+        $this->initialize();
+
+        return $this->coll->get($key);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getKeys()
+    {
+        $this->initialize();
+
+        return $this->coll->getKeys();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValues()
+    {
+        $this->initialize();
+
+        return $this->coll->getValues();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count()
+    {
+        if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) {
+            $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
+
+            return $persister->count($this) + ($this->isDirty ? $this->coll->count() : 0);
+        }
+
+        $this->initialize();
+
+        return $this->coll->count();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value)
+    {
+        $this->initialize();
+
+        $this->coll->set($key, $value);
+
+        $this->changed();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function add($value)
+    {
+        $this->coll->add($value);
+
+        $this->changed();
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isEmpty()
+    {
+        $this->initialize();
+
+        return $this->coll->isEmpty();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $this->initialize();
+
+        return $this->coll->getIterator();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function map(Closure $func)
+    {
+        $this->initialize();
+
+        return $this->coll->map($func);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filter(Closure $p)
+    {
+        $this->initialize();
+
+        return $this->coll->filter($p);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function forAll(Closure $p)
+    {
+        $this->initialize();
+
+        return $this->coll->forAll($p);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function partition(Closure $p)
+    {
+        $this->initialize();
+
+        return $this->coll->partition($p);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function toArray()
+    {
+        $this->initialize();
+
+        return $this->coll->toArray();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        if ($this->initialized && $this->isEmpty()) {
+            return;
+        }
+
+        $uow = $this->em->getUnitOfWork();
+
+        if ($this->association['type'] & ClassMetadata::TO_MANY &&
+            $this->association['orphanRemoval'] &&
+            $this->owner) {
+            // we need to initialize here, as orphan removal acts like implicit cascadeRemove,
+            // hence for event listeners we need the objects in memory.
+            $this->initialize();
+
+            foreach ($this->coll as $element) {
+                $uow->scheduleOrphanRemoval($element);
+            }
+        }
+
+        $this->coll->clear();
+
+        $this->initialized = true; // direct call, {@link initialize()} is too expensive
+
+        if ($this->association['isOwningSide']) {
+            $this->changed();
+
+            $uow->scheduleCollectionDeletion($this);
+
+            $this->takeSnapshot();
+        }
+    }
+
+    /**
+     * Called by PHP when this collection is serialized. Ensures that only the
+     * elements are properly serialized.
+     *
+     * @internal Tried to implement Serializable first but that did not work well
+     *           with circular references. This solution seems simpler and works well.
+     */
+    public function __sleep()
+    {
+        return array('coll', 'initialized');
+    }
+
+    /* ArrayAccess implementation */
+
+    /**
+     * @see containsKey()
+     */
+    public function offsetExists($offset)
+    {
+        return $this->containsKey($offset);
+    }
+
+    /**
+     * @see get()
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * @see add()
+     * @see set()
+     */
+    public function offsetSet($offset, $value)
+    {
+        if ( ! isset($offset)) {
+            return $this->add($value);
+        }
+
+        return $this->set($offset, $value);
+    }
+
+    /**
+     * @see remove()
+     */
+    public function offsetUnset($offset)
+    {
+        return $this->remove($offset);
+    }
+
+    public function key()
+    {
+        return $this->coll->key();
+    }
+
+    /**
+     * Gets the element of the collection at the current iterator position.
+     */
+    public function current()
+    {
+        return $this->coll->current();
+    }
+
+    /**
+     * Moves the internal iterator position to the next element.
+     */
+    public function next()
+    {
+        return $this->coll->next();
+    }
+
+    /**
+     * Retrieves the wrapped Collection instance.
+     *
+     * @return \Doctrine\Common\Collections\Collection
+     */
+    public function unwrap()
+    {
+        return $this->coll;
+    }
+
+    /**
+     * Extract a slice of $length elements starting at position $offset from the Collection.
+     *
+     * If $length is null it returns all elements from $offset to the end of the Collection.
+     * Keys have to be preserved by this method. Calling this method will only return the
+     * selected slice and NOT change the elements contained in the collection slice is called on.
+     *
+     * @param int $offset
+     * @param int $length
+     *
+     * @return array
+     */
+    public function slice($offset, $length = null)
+    {
+        if ( ! $this->initialized && ! $this->isDirty && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) {
+            $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
+
+            return $persister->slice($this, $offset, $length);
+        }
+
+        $this->initialize();
+
+        return $this->coll->slice($offset, $length);
+    }
+
+    /**
+     * Cleanup internal state of cloned persistent collection.
+     *
+     * The following problems have to be prevented:
+     * 1. Added entities are added to old PC
+     * 2. New collection is not dirty, if reused on other entity nothing
+     * changes.
+     * 3. Snapshot leads to invalid diffs being generated.
+     * 4. Lazy loading grabs entities from old owner object.
+     * 5. New collection is connected to old owner and leads to duplicate keys.
+     */
+    public function __clone()
+    {
+        if (is_object($this->coll)) {
+            $this->coll = clone $this->coll;
+        }
+
+        $this->initialize();
+        $this->owner = null;
+
+        $this->snapshot = array();
+
+        $this->changed();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractCollectionPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractCollectionPersister.php	(revision 345)
@@ -0,0 +1,207 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\EntityManager,
+    Doctrine\ORM\PersistentCollection;
+
+/**
+ * Base class for all collection persisters.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+abstract class AbstractCollectionPersister
+{
+    /**
+     * @var EntityManager
+     */
+    protected $_em;
+
+    /**
+     * @var \Doctrine\DBAL\Connection
+     */
+    protected $_conn;
+
+    /**
+     * @var \Doctrine\ORM\UnitOfWork
+     */
+    protected $_uow;
+
+    /**
+     * Initializes a new instance of a class derived from AbstractCollectionPersister.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em = $em;
+        $this->_uow = $em->getUnitOfWork();
+        $this->_conn = $em->getConnection();
+    }
+
+    /**
+     * Deletes the persistent state represented by the given collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    public function delete(PersistentCollection $coll)
+    {
+        $mapping = $coll->getMapping();
+
+        if ( ! $mapping['isOwningSide']) {
+            return; // ignore inverse side
+        }
+
+        $sql = $this->_getDeleteSQL($coll);
+        $this->_conn->executeUpdate($sql, $this->_getDeleteSQLParameters($coll));
+    }
+
+    /**
+     * Gets the SQL statement for deleting the given collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    abstract protected function _getDeleteSQL(PersistentCollection $coll);
+
+    /**
+     * Gets the SQL parameters for the corresponding SQL statement to delete
+     * the given collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    abstract protected function _getDeleteSQLParameters(PersistentCollection $coll);
+
+    /**
+     * Updates the given collection, synchronizing it's state with the database
+     * by inserting, updating and deleting individual elements.
+     *
+     * @param PersistentCollection $coll
+     */
+    public function update(PersistentCollection $coll)
+    {
+        $mapping = $coll->getMapping();
+
+        if ( ! $mapping['isOwningSide']) {
+            return; // ignore inverse side
+        }
+
+        $this->deleteRows($coll);
+        //$this->updateRows($coll);
+        $this->insertRows($coll);
+    }
+
+    public function deleteRows(PersistentCollection $coll)
+    {
+        $deleteDiff = $coll->getDeleteDiff();
+        $sql = $this->_getDeleteRowSQL($coll);
+
+        foreach ($deleteDiff as $element) {
+            $this->_conn->executeUpdate($sql, $this->_getDeleteRowSQLParameters($coll, $element));
+        }
+    }
+
+    //public function updateRows(PersistentCollection $coll)
+    //{}
+
+    public function insertRows(PersistentCollection $coll)
+    {
+        $insertDiff = $coll->getInsertDiff();
+        $sql = $this->_getInsertRowSQL($coll);
+
+        foreach ($insertDiff as $element) {
+            $this->_conn->executeUpdate($sql, $this->_getInsertRowSQLParameters($coll, $element));
+        }
+    }
+
+    public function count(PersistentCollection $coll)
+    {
+        throw new \BadMethodCallException("Counting the size of this persistent collection is not supported by this CollectionPersister.");
+    }
+
+    public function slice(PersistentCollection $coll, $offset, $length = null)
+    {
+        throw new \BadMethodCallException("Slicing elements is not supported by this CollectionPersister.");
+    }
+
+    public function contains(PersistentCollection $coll, $element)
+    {
+        throw new \BadMethodCallException("Checking for existance of an element is not supported by this CollectionPersister.");
+    }
+
+    public function containsKey(PersistentCollection $coll, $key)
+    {
+        throw new \BadMethodCallException("Checking for existance of a key is not supported by this CollectionPersister.");
+    }
+
+    public function removeElement(PersistentCollection $coll, $element)
+    {
+        throw new \BadMethodCallException("Removing an element is not supported by this CollectionPersister.");
+    }
+
+    public function removeKey(PersistentCollection $coll, $key)
+    {
+        throw new \BadMethodCallException("Removing a key is not supported by this CollectionPersister.");
+    }
+
+    public function get(PersistentCollection $coll, $index)
+    {
+        throw new \BadMethodCallException("Selecting a collection by index is not supported by this CollectionPersister.");
+    }
+
+    /**
+     * Gets the SQL statement used for deleting a row from the collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    abstract protected function _getDeleteRowSQL(PersistentCollection $coll);
+
+    /**
+     * Gets the SQL parameters for the corresponding SQL statement to delete the given
+     * element from the given collection.
+     *
+     * @param PersistentCollection $coll
+     * @param mixed $element
+     */
+    abstract protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element);
+
+    /**
+     * Gets the SQL statement used for updating a row in the collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    abstract protected function _getUpdateRowSQL(PersistentCollection $coll);
+
+    /**
+     * Gets the SQL statement used for inserting a row in the collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    abstract protected function _getInsertRowSQL(PersistentCollection $coll);
+
+    /**
+     * Gets the SQL parameters for the corresponding SQL statement to insert the given
+     * element of the given collection into the database.
+     *
+     * @param PersistentCollection $coll
+     * @param mixed $element
+     */
+    abstract protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php	(revision 345)
@@ -0,0 +1,83 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\DBAL\Types\Type;
+
+/**
+ * Base class for entity persisters that implement a certain inheritance mapping strategy.
+ * All these persisters are assumed to use a discriminator column to discriminate entity
+ * types in the hierarchy.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.0
+ */
+abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _prepareInsertData($entity)
+    {
+        $data = parent::_prepareInsertData($entity);
+
+        // Populate the discriminator column
+        $discColumn = $this->_class->discriminatorColumn;
+        $this->_columnTypes[$discColumn['name']] = $discColumn['type'];
+        $data[$this->_getDiscriminatorColumnTableName()][$discColumn['name']] = $this->_class->discriminatorValue;
+
+        return $data;
+    }
+
+    /**
+     * Gets the name of the table that contains the discriminator column.
+     *
+     * @return string The table name.
+     */
+    abstract protected function _getDiscriminatorColumnTableName();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
+    {
+        $columnName = $class->columnNames[$field];
+        $sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) . '.' . $class->getQuotedColumnName($field, $this->_platform);
+        $columnAlias = $this->getSQLColumnAlias($columnName);
+        $this->_rsm->addFieldResult($alias, $columnAlias, $field, $class->name);
+
+        if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
+            $type = Type::getType($class->getTypeOfField($field));
+            $sql = $type->convertToPHPValueSQL($sql, $this->_platform);
+        }
+
+        return $sql . ' AS ' . $columnAlias;
+    }
+
+    protected function getSelectJoinColumnSQL($tableAlias, $joinColumnName, $className)
+    {
+        $columnAlias = $this->getSQLColumnAlias($joinColumnName);
+        $this->_rsm->addMetaResult('r', $columnAlias, $joinColumnName);
+
+        return $tableAlias . '.' . $joinColumnName . ' AS ' . $columnAlias;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/BasicEntityPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/BasicEntityPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/BasicEntityPersister.php	(revision 345)
@@ -0,0 +1,1617 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use PDO,
+    Doctrine\DBAL\LockMode,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Connection,
+    Doctrine\ORM\ORMException,
+    Doctrine\ORM\OptimisticLockException,
+    Doctrine\ORM\EntityManager,
+    Doctrine\ORM\UnitOfWork,
+    Doctrine\ORM\Query,
+    Doctrine\ORM\PersistentCollection,
+    Doctrine\ORM\Mapping\MappingException,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Events,
+    Doctrine\ORM\Event\LifecycleEventArgs;
+
+/**
+ * A BasicEntityPersiter maps an entity to a single table in a relational database.
+ *
+ * A persister is always responsible for a single entity type.
+ *
+ * EntityPersisters are used during a UnitOfWork to apply any changes to the persistent
+ * state of entities onto a relational database when the UnitOfWork is committed,
+ * as well as for basic querying of entities and their associations (not DQL).
+ *
+ * The persisting operations that are invoked during a commit of a UnitOfWork to
+ * persist the persistent entity state are:
+ *
+ *   - {@link addInsert} : To schedule an entity for insertion.
+ *   - {@link executeInserts} : To execute all scheduled insertions.
+ *   - {@link update} : To update the persistent state of an entity.
+ *   - {@link delete} : To delete the persistent state of an entity.
+ *
+ * As can be seen from the above list, insertions are batched and executed all at once
+ * for increased efficiency.
+ *
+ * The querying operations invoked during a UnitOfWork, either through direct find
+ * requests or lazy-loading, are the following:
+ *
+ *   - {@link load} : Loads (the state of) a single, managed entity.
+ *   - {@link loadAll} : Loads multiple, managed entities.
+ *   - {@link loadOneToOneEntity} : Loads a one/many-to-one entity association (lazy-loading).
+ *   - {@link loadOneToManyCollection} : Loads a one-to-many entity association (lazy-loading).
+ *   - {@link loadManyToManyCollection} : Loads a many-to-many entity association (lazy-loading).
+ *
+ * The BasicEntityPersister implementation provides the default behavior for
+ * persisting and querying entities that are mapped to a single database table.
+ *
+ * Subclasses can be created to provide custom persisting and querying strategies,
+ * i.e. spanning multiple tables.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Alexander <iam.asm89@gmail.com>
+ * @since 2.0
+ */
+class BasicEntityPersister
+{
+    /**
+     * Metadata object that describes the mapping of the mapped entity class.
+     *
+     * @var \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    protected $_class;
+
+    /**
+     * The underlying DBAL Connection of the used EntityManager.
+     *
+     * @var \Doctrine\DBAL\Connection $conn
+     */
+    protected $_conn;
+
+    /**
+     * The database platform.
+     *
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    protected $_platform;
+
+    /**
+     * The EntityManager instance.
+     *
+     * @var \Doctrine\ORM\EntityManager
+     */
+    protected $_em;
+
+    /**
+     * Queued inserts.
+     *
+     * @var array
+     */
+    protected $_queuedInserts = array();
+
+    /**
+     * ResultSetMapping that is used for all queries. Is generated lazily once per request.
+     *
+     * TODO: Evaluate Caching in combination with the other cached SQL snippets.
+     *
+     * @var Query\ResultSetMapping
+     */
+    protected $_rsm;
+
+    /**
+     * The map of column names to DBAL mapping types of all prepared columns used
+     * when INSERTing or UPDATEing an entity.
+     *
+     * @var array
+     * @see _prepareInsertData($entity)
+     * @see _prepareUpdateData($entity)
+     */
+    protected $_columnTypes = array();
+
+    /**
+     * The INSERT SQL statement used for entities handled by this persister.
+     * This SQL is only generated once per request, if at all.
+     *
+     * @var string
+     */
+    private $_insertSql;
+
+    /**
+     * The SELECT column list SQL fragment used for querying entities by this persister.
+     * This SQL fragment is only generated once per request, if at all.
+     *
+     * @var string
+     */
+    protected $_selectColumnListSql;
+
+    /**
+     * The JOIN SQL fragement used to eagerly load all many-to-one and one-to-one
+     * associations configured as FETCH_EAGER, aswell as all inverse one-to-one associations.
+     *
+     * @var string
+     */
+    protected $_selectJoinSql;
+
+    /**
+     * Counter for creating unique SQL table and column aliases.
+     *
+     * @var integer
+     */
+    protected $_sqlAliasCounter = 0;
+
+    /**
+     * Map from class names (FQCN) to the corresponding generated SQL table aliases.
+     *
+     * @var array
+     */
+    protected $_sqlTableAliases = array();
+
+    /**
+     * Initializes a new <tt>BasicEntityPersister</tt> that uses the given EntityManager
+     * and persists instances of the class described by the given ClassMetadata descriptor.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     */
+    public function __construct(EntityManager $em, ClassMetadata $class)
+    {
+        $this->_em = $em;
+        $this->_class = $class;
+        $this->_conn = $em->getConnection();
+        $this->_platform = $this->_conn->getDatabasePlatform();
+    }
+
+    /**
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    public function getClassMetadata()
+    {
+        return $this->_class;
+    }
+
+    /**
+     * Adds an entity to the queued insertions.
+     * The entity remains queued until {@link executeInserts} is invoked.
+     *
+     * @param object $entity The entity to queue for insertion.
+     */
+    public function addInsert($entity)
+    {
+        $this->_queuedInserts[spl_object_hash($entity)] = $entity;
+    }
+
+    /**
+     * Executes all queued entity insertions and returns any generated post-insert
+     * identifiers that were created as a result of the insertions.
+     *
+     * If no inserts are queued, invoking this method is a NOOP.
+     *
+     * @return array An array of any generated post-insert IDs. This will be an empty array
+     *               if the entity class does not use the IDENTITY generation strategy.
+     */
+    public function executeInserts()
+    {
+        if ( ! $this->_queuedInserts) {
+            return;
+        }
+
+        $postInsertIds = array();
+        $idGen = $this->_class->idGenerator;
+        $isPostInsertId = $idGen->isPostInsertGenerator();
+
+        $stmt = $this->_conn->prepare($this->_getInsertSQL());
+        $tableName = $this->_class->getTableName();
+
+        foreach ($this->_queuedInserts as $entity) {
+            $insertData = $this->_prepareInsertData($entity);
+
+            if (isset($insertData[$tableName])) {
+                $paramIndex = 1;
+
+                foreach ($insertData[$tableName] as $column => $value) {
+                    $stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$column]);
+                }
+            }
+
+            $stmt->execute();
+
+            if ($isPostInsertId) {
+                $id = $idGen->generate($this->_em, $entity);
+                $postInsertIds[$id] = $entity;
+            } else {
+                $id = $this->_class->getIdentifierValues($entity);
+            }
+
+            if ($this->_class->isVersioned) {
+                $this->assignDefaultVersionValue($entity, $id);
+            }
+        }
+
+        $stmt->closeCursor();
+        $this->_queuedInserts = array();
+
+        return $postInsertIds;
+    }
+
+    /**
+     * Retrieves the default version value which was created
+     * by the preceding INSERT statement and assigns it back in to the
+     * entities version field.
+     *
+     * @param object $entity
+     * @param mixed $id
+     */
+    protected function assignDefaultVersionValue($entity, $id)
+    {
+        $value = $this->fetchVersionValue($this->_class, $id);
+        $this->_class->setFieldValue($entity, $this->_class->versionField, $value);
+    }
+
+    /**
+     * Fetch the current version value of a versioned entity.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $versionedClass
+     * @param mixed $id
+     * @return mixed
+     */
+    protected function fetchVersionValue($versionedClass, $id)
+    {
+        $versionField = $versionedClass->versionField;
+        $identifier   = $versionedClass->getIdentifierColumnNames();
+
+        $versionFieldColumnName = $versionedClass->getQuotedColumnName($versionField, $this->_platform);
+
+        //FIXME: Order with composite keys might not be correct
+        $sql = 'SELECT ' . $versionFieldColumnName
+             . ' FROM ' . $versionedClass->getQuotedTableName($this->_platform)
+             . ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';
+        $value = $this->_conn->fetchColumn($sql, array_values((array)$id));
+
+        return Type::getType($versionedClass->fieldMappings[$versionField]['type'])->convertToPHPValue($value, $this->_platform);
+    }
+
+    /**
+     * Updates a managed entity. The entity is updated according to its current changeset
+     * in the running UnitOfWork. If there is no changeset, nothing is updated.
+     *
+     * The data to update is retrieved through {@link _prepareUpdateData}.
+     * Subclasses that override this method are supposed to obtain the update data
+     * in the same way, through {@link _prepareUpdateData}.
+     *
+     * Subclasses are also supposed to take care of versioning when overriding this method,
+     * if necessary. The {@link _updateTable} method can be used to apply the data retrieved
+     * from {@_prepareUpdateData} on the target tables, thereby optionally applying versioning.
+     *
+     * @param object $entity The entity to update.
+     */
+    public function update($entity)
+    {
+        $updateData = $this->_prepareUpdateData($entity);
+        $tableName  = $this->_class->getTableName();
+
+        if (isset($updateData[$tableName]) && $updateData[$tableName]) {
+            $this->_updateTable(
+                $entity, $this->_class->getQuotedTableName($this->_platform),
+                $updateData[$tableName], $this->_class->isVersioned
+            );
+
+            if ($this->_class->isVersioned) {
+                $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+                $this->assignDefaultVersionValue($entity, $id);
+            }
+        }
+    }
+
+    /**
+     * Performs an UPDATE statement for an entity on a specific table.
+     * The UPDATE can optionally be versioned, which requires the entity to have a version field.
+     *
+     * @param object $entity The entity object being updated.
+     * @param string $quotedTableName The quoted name of the table to apply the UPDATE on.
+     * @param array $updateData The map of columns to update (column => value).
+     * @param boolean $versioned Whether the UPDATE should be versioned.
+     */
+    protected final function _updateTable($entity, $quotedTableName, array $updateData, $versioned = false)
+    {
+        $set = $params = $types = array();
+
+        foreach ($updateData as $columnName => $value) {
+            $column = $columnName;
+            $placeholder = '?';
+
+            if (isset($this->_class->fieldNames[$columnName])) {
+                $column = $this->_class->getQuotedColumnName($this->_class->fieldNames[$columnName], $this->_platform);
+
+                if (isset($this->_class->fieldMappings[$this->_class->fieldNames[$columnName]]['requireSQLConversion'])) {
+                    $type = Type::getType($this->_columnTypes[$columnName]);
+                    $placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
+                }
+            }
+
+            $set[] = $column . ' = ' . $placeholder;
+            $params[] = $value;
+            $types[] = $this->_columnTypes[$columnName];
+        }
+
+        $where = array();
+        $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+
+        foreach ($this->_class->identifier as $idField) {
+            if (isset($this->_class->associationMappings[$idField])) {
+                $targetMapping = $this->_em->getClassMetadata($this->_class->associationMappings[$idField]['targetEntity']);
+                $where[] = $this->_class->associationMappings[$idField]['joinColumns'][0]['name'];
+                $params[] = $id[$idField];
+
+                switch (true) {
+                    case (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])):
+                        $types[] = $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
+                        break;
+
+                    case (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])):
+                        $types[] = $targetMapping->associationMappings[$targetMapping->identifier[0]]['type'];
+                        break;
+
+                    default:
+                        throw ORMException::unrecognizedField($targetMapping->identifier[0]);
+                }
+            } else {
+                $where[] = $this->_class->getQuotedColumnName($idField, $this->_platform);
+                $params[] = $id[$idField];
+                $types[] = $this->_class->fieldMappings[$idField]['type'];
+            }
+        }
+
+        if ($versioned) {
+            $versionField = $this->_class->versionField;
+            $versionFieldType = $this->_class->fieldMappings[$versionField]['type'];
+            $versionColumn = $this->_class->getQuotedColumnName($versionField, $this->_platform);
+
+            if ($versionFieldType == Type::INTEGER) {
+                $set[] = $versionColumn . ' = ' . $versionColumn . ' + 1';
+            } else if ($versionFieldType == Type::DATETIME) {
+                $set[] = $versionColumn . ' = CURRENT_TIMESTAMP';
+            }
+
+            $where[] = $versionColumn;
+            $params[] = $this->_class->reflFields[$versionField]->getValue($entity);
+            $types[] = $this->_class->fieldMappings[$versionField]['type'];
+        }
+
+        $sql = 'UPDATE ' . $quotedTableName
+             . ' SET ' . implode(', ', $set)
+             . ' WHERE ' . implode(' = ? AND ', $where) . ' = ?';
+
+        $result = $this->_conn->executeUpdate($sql, $params, $types);
+
+        if ($versioned && ! $result) {
+            throw OptimisticLockException::lockFailed($entity);
+        }
+    }
+
+    /**
+     * @todo Add check for platform if it supports foreign keys/cascading.
+     * @param array $identifier
+     * @return void
+     */
+    protected function deleteJoinTableRecords($identifier)
+    {
+        foreach ($this->_class->associationMappings as $mapping) {
+            if ($mapping['type'] == ClassMetadata::MANY_TO_MANY) {
+                // @Todo this only covers scenarios with no inheritance or of the same level. Is there something
+                // like self-referential relationship between different levels of an inheritance hierachy? I hope not!
+                $selfReferential = ($mapping['targetEntity'] == $mapping['sourceEntity']);
+
+                if ( ! $mapping['isOwningSide']) {
+                    $relatedClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+                    $mapping = $relatedClass->associationMappings[$mapping['mappedBy']];
+                    $keys = array_keys($mapping['relationToTargetKeyColumns']);
+
+                    if ($selfReferential) {
+                        $otherKeys = array_keys($mapping['relationToSourceKeyColumns']);
+                    }
+                } else {
+                    $keys = array_keys($mapping['relationToSourceKeyColumns']);
+
+                    if ($selfReferential) {
+                        $otherKeys = array_keys($mapping['relationToTargetKeyColumns']);
+                    }
+                }
+
+                if ( ! isset($mapping['isOnDeleteCascade'])) {
+                    $this->_conn->delete(
+                        $this->_class->getQuotedJoinTableName($mapping, $this->_platform),
+                        array_combine($keys, $identifier)
+                    );
+
+                    if ($selfReferential) {
+                        $this->_conn->delete(
+                            $this->_class->getQuotedJoinTableName($mapping, $this->_platform),
+                            array_combine($otherKeys, $identifier)
+                        );
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Deletes a managed entity.
+     *
+     * The entity to delete must be managed and have a persistent identifier.
+     * The deletion happens instantaneously.
+     *
+     * Subclasses may override this method to customize the semantics of entity deletion.
+     *
+     * @param object $entity The entity to delete.
+     */
+    public function delete($entity)
+    {
+        $identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+        $this->deleteJoinTableRecords($identifier);
+
+        $id = array_combine($this->_class->getIdentifierColumnNames(), $identifier);
+        $this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id);
+    }
+
+    /**
+     * Prepares the changeset of an entity for database insertion (UPDATE).
+     *
+     * The changeset is obtained from the currently running UnitOfWork.
+     *
+     * During this preparation the array that is passed as the second parameter is filled with
+     * <columnName> => <value> pairs, grouped by table name.
+     *
+     * Example:
+     * <code>
+     * array(
+     *    'foo_table' => array('column1' => 'value1', 'column2' => 'value2', ...),
+     *    'bar_table' => array('columnX' => 'valueX', 'columnY' => 'valueY', ...),
+     *    ...
+     * )
+     * </code>
+     *
+     * @param object $entity The entity for which to prepare the data.
+     * @return array The prepared data.
+     */
+    protected function _prepareUpdateData($entity)
+    {
+        $result = array();
+        $uow = $this->_em->getUnitOfWork();
+
+        if (($versioned = $this->_class->isVersioned) != false) {
+            $versionField = $this->_class->versionField;
+        }
+
+        foreach ($uow->getEntityChangeSet($entity) as $field => $change) {
+            if ($versioned && $versionField == $field) {
+                continue;
+            }
+
+            $oldVal = $change[0];
+            $newVal = $change[1];
+
+            if (isset($this->_class->associationMappings[$field])) {
+                $assoc = $this->_class->associationMappings[$field];
+
+                // Only owning side of x-1 associations can have a FK column.
+                if ( ! $assoc['isOwningSide'] || ! ($assoc['type'] & ClassMetadata::TO_ONE)) {
+                    continue;
+                }
+
+                if ($newVal !== null) {
+                    $oid = spl_object_hash($newVal);
+
+                    if (isset($this->_queuedInserts[$oid]) || $uow->isScheduledForInsert($newVal)) {
+                        // The associated entity $newVal is not yet persisted, so we must
+                        // set $newVal = null, in order to insert a null value and schedule an
+                        // extra update on the UnitOfWork.
+                        $uow->scheduleExtraUpdate($entity, array(
+                            $field => array(null, $newVal)
+                        ));
+                        $newVal = null;
+                    }
+                }
+
+                if ($newVal !== null) {
+                    $newValId = $uow->getEntityIdentifier($newVal);
+                }
+
+                $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
+                $owningTable = $this->getOwningTable($field);
+
+                foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
+                    if ($newVal === null) {
+                        $result[$owningTable][$sourceColumn] = null;
+                    } else if ($targetClass->containsForeignIdentifier) {
+                        $result[$owningTable][$sourceColumn] = $newValId[$targetClass->getFieldForColumn($targetColumn)];
+                    } else {
+                        $result[$owningTable][$sourceColumn] = $newValId[$targetClass->fieldNames[$targetColumn]];
+                    }
+
+                    $this->_columnTypes[$sourceColumn] = $targetClass->getTypeOfColumn($targetColumn);
+                }
+            } else {
+                $columnName = $this->_class->columnNames[$field];
+                $this->_columnTypes[$columnName] = $this->_class->fieldMappings[$field]['type'];
+                $result[$this->getOwningTable($field)][$columnName] = $newVal;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Prepares the data changeset of a managed entity for database insertion (initial INSERT).
+     * The changeset of the entity is obtained from the currently running UnitOfWork.
+     *
+     * The default insert data preparation is the same as for updates.
+     *
+     * @param object $entity The entity for which to prepare the data.
+     * @return array The prepared data for the tables to update.
+     * @see _prepareUpdateData
+     */
+    protected function _prepareInsertData($entity)
+    {
+        return $this->_prepareUpdateData($entity);
+    }
+
+    /**
+     * Gets the name of the table that owns the column the given field is mapped to.
+     *
+     * The default implementation in BasicEntityPersister always returns the name
+     * of the table the entity type of this persister is mapped to, since an entity
+     * is always persisted to a single table with a BasicEntityPersister.
+     *
+     * @param string $fieldName The field name.
+     * @return string The table name.
+     */
+    public function getOwningTable($fieldName)
+    {
+        return $this->_class->getTableName();
+    }
+
+    /**
+     * Loads an entity by a list of field criteria.
+     *
+     * @param array $criteria The criteria by which to load the entity.
+     * @param object $entity The entity to load the data into. If not specified,
+     *        a new entity is created.
+     * @param $assoc The association that connects the entity to load to another entity, if any.
+     * @param array $hints Hints for entity creation.
+     * @param int $lockMode
+     * @param int $limit Limit number of results
+     * @return object The loaded and managed entity instance or NULL if the entity can not be found.
+     * @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
+     */
+    public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null)
+    {
+        $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit);
+        list($params, $types) = $this->expandParameters($criteria);
+        $stmt = $this->_conn->executeQuery($sql, $params, $types);
+
+        if ($entity !== null) {
+            $hints[Query::HINT_REFRESH] = true;
+            $hints[Query::HINT_REFRESH_ENTITY] = $entity;
+        }
+
+        $hydrator = $this->_em->newHydrator($this->_selectJoinSql ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
+        $entities = $hydrator->hydrateAll($stmt, $this->_rsm, $hints);
+
+        return $entities ? $entities[0] : null;
+    }
+
+    /**
+     * Loads an entity of this persister's mapped class as part of a single-valued
+     * association from another entity.
+     *
+     * @param array $assoc The association to load.
+     * @param object $sourceEntity The entity that owns the association (not necessarily the "owning side").
+     * @param array $identifier The identifier of the entity to load. Must be provided if
+     *                          the association to load represents the owning side, otherwise
+     *                          the identifier is derived from the $sourceEntity.
+     * @return object The loaded and managed entity instance or NULL if the entity can not be found.
+     */
+    public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = array())
+    {
+        if (($foundEntity = $this->_em->getUnitOfWork()->tryGetById($identifier, $assoc['targetEntity'])) != false) {
+            return $foundEntity;
+        }
+
+        $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
+
+        if ($assoc['isOwningSide']) {
+            $isInverseSingleValued = $assoc['inversedBy'] && ! $targetClass->isCollectionValuedAssociation($assoc['inversedBy']);
+
+            // Mark inverse side as fetched in the hints, otherwise the UoW would
+            // try to load it in a separate query (remember: to-one inverse sides can not be lazy).
+            $hints = array();
+
+            if ($isInverseSingleValued) {
+                $hints['fetched']["r"][$assoc['inversedBy']] = true;
+            }
+
+            /* cascade read-only status
+            if ($this->_em->getUnitOfWork()->isReadOnly($sourceEntity)) {
+                $hints[Query::HINT_READ_ONLY] = true;
+            }
+            */
+
+            $targetEntity = $this->load($identifier, null, $assoc, $hints);
+
+            // Complete bidirectional association, if necessary
+            if ($targetEntity !== null && $isInverseSingleValued) {
+                $targetClass->reflFields[$assoc['inversedBy']]->setValue($targetEntity, $sourceEntity);
+            }
+        } else {
+            $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']);
+            $owningAssoc = $targetClass->getAssociationMapping($assoc['mappedBy']);
+
+            // TRICKY: since the association is specular source and target are flipped
+            foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) {
+                if ( ! isset($sourceClass->fieldNames[$sourceKeyColumn])) {
+                    throw MappingException::joinColumnMustPointToMappedField(
+                        $sourceClass->name, $sourceKeyColumn
+                    );
+                }
+
+                // unset the old value and set the new sql aliased value here. By definition
+                // unset($identifier[$targetKeyColumn] works here with how UnitOfWork::createEntity() calls this method.
+                $identifier[$this->_getSQLTableAlias($targetClass->name) . "." . $targetKeyColumn] =
+                    $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
+
+                unset($identifier[$targetKeyColumn]);
+            }
+
+            $targetEntity = $this->load($identifier, null, $assoc);
+
+            if ($targetEntity !== null) {
+                $targetClass->setFieldValue($targetEntity, $assoc['mappedBy'], $sourceEntity);
+            }
+        }
+
+        return $targetEntity;
+    }
+
+    /**
+     * Refreshes a managed entity.
+     *
+     * @param array $id The identifier of the entity as an associative array from
+     *                  column or field names to values.
+     * @param object $entity The entity to refresh.
+     */
+    public function refresh(array $id, $entity, $lockMode = 0)
+    {
+        $sql = $this->_getSelectEntitiesSQL($id, null, $lockMode);
+        list($params, $types) = $this->expandParameters($id);
+        $stmt = $this->_conn->executeQuery($sql, $params, $types);
+
+        $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT);
+        $hydrator->hydrateAll($stmt, $this->_rsm, array(Query::HINT_REFRESH => true));
+    }
+
+    /**
+     * Loads a list of entities by a list of field criteria.
+     *
+     * @param array $criteria
+     * @param array $orderBy
+     * @param int $limit
+     * @param int $offset
+     * @return array
+     */
+    public function loadAll(array $criteria = array(), array $orderBy = null, $limit = null, $offset = null)
+    {
+        $entities = array();
+        $sql = $this->_getSelectEntitiesSQL($criteria, null, 0, $limit, $offset, $orderBy);
+        list($params, $types) = $this->expandParameters($criteria);
+        $stmt = $this->_conn->executeQuery($sql, $params, $types);
+
+        $hydrator = $this->_em->newHydrator(($this->_selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
+
+        return $hydrator->hydrateAll($stmt, $this->_rsm, array('deferEagerLoads' => true));
+    }
+
+    /**
+     * Get (sliced or full) elements of the given collection.
+     *
+     * @param array $assoc
+     * @param object $sourceEntity
+     * @param int|null $offset
+     * @param int|null $limit
+     * @return array
+     */
+    public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
+    {
+        $stmt = $this->getManyToManyStatement($assoc, $sourceEntity, $offset, $limit);
+
+        return $this->loadArrayFromStatement($assoc, $stmt);
+    }
+
+    /**
+     * Load an array of entities from a given dbal statement.
+     *
+     * @param array $assoc
+     * @param \Doctrine\DBAL\Statement $stmt
+     *
+     * @return array
+     */
+    private function loadArrayFromStatement($assoc, $stmt)
+    {
+        $hints = array('deferEagerLoads' => true);
+
+        if (isset($assoc['indexBy'])) {
+            $rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed.
+            $rsm->addIndexBy('r', $assoc['indexBy']);
+        } else {
+            $rsm = $this->_rsm;
+        }
+
+        $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT);
+
+        return $hydrator->hydrateAll($stmt, $rsm, $hints);
+    }
+
+    /**
+     * Hydrate a collection from a given dbal statement.
+     *
+     * @param array $assoc
+     * @param \Doctrine\DBAL\Statement $stmt
+     * @param PersistentCollection $coll
+     *
+     * @return array
+     */
+    private function loadCollectionFromStatement($assoc, $stmt, $coll)
+    {
+        $hints = array('deferEagerLoads' => true, 'collection' => $coll);
+
+        if (isset($assoc['indexBy'])) {
+            $rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed.
+            $rsm->addIndexBy('r', $assoc['indexBy']);
+        } else {
+            $rsm = $this->_rsm;
+        }
+
+        $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT);
+
+        return $hydrator->hydrateAll($stmt, $rsm, $hints);
+    }
+
+    /**
+     * Loads a collection of entities of a many-to-many association.
+     *
+     * @param ManyToManyMapping $assoc The association mapping of the association being loaded.
+     * @param object $sourceEntity The entity that owns the collection.
+     * @param PersistentCollection $coll The collection to fill.
+     * @param int|null $offset
+     * @param int|null $limit
+     * @return array
+     */
+    public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
+    {
+        $stmt = $this->getManyToManyStatement($assoc, $sourceEntity);
+
+        return $this->loadCollectionFromStatement($assoc, $stmt, $coll);
+    }
+
+    private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
+    {
+        $criteria = array();
+        $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']);
+
+        if ($assoc['isOwningSide']) {
+            $quotedJoinTable = $sourceClass->getQuotedJoinTableName($assoc, $this->_platform);
+
+            foreach ($assoc['relationToSourceKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) {
+                if ($sourceClass->containsForeignIdentifier) {
+                    $field = $sourceClass->getFieldForColumn($sourceKeyColumn);
+                    $value = $sourceClass->reflFields[$field]->getValue($sourceEntity);
+
+                    if (isset($sourceClass->associationMappings[$field])) {
+                        $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+                        $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]];
+                    }
+
+                    $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value;
+                } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
+                    $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
+                } else {
+                    throw MappingException::joinColumnMustPointToMappedField(
+                        $sourceClass->name, $sourceKeyColumn
+                    );
+                }
+            }
+        } else {
+            $owningAssoc = $this->_em->getClassMetadata($assoc['targetEntity'])->associationMappings[$assoc['mappedBy']];
+            $quotedJoinTable = $sourceClass->getQuotedJoinTableName($owningAssoc, $this->_platform);
+
+            // TRICKY: since the association is inverted source and target are flipped
+            foreach ($owningAssoc['relationToTargetKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) {
+                if ($sourceClass->containsForeignIdentifier) {
+                    $field = $sourceClass->getFieldForColumn($sourceKeyColumn);
+                    $value = $sourceClass->reflFields[$field]->getValue($sourceEntity);
+
+                    if (isset($sourceClass->associationMappings[$field])) {
+                        $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+                        $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]];
+                    }
+
+                    $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value;
+                } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
+                    $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
+                } else {
+                    throw MappingException::joinColumnMustPointToMappedField(
+                        $sourceClass->name, $sourceKeyColumn
+                    );
+                }
+            }
+        }
+
+        $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, 0, $limit, $offset);
+        list($params, $types) = $this->expandParameters($criteria);
+
+        return $this->_conn->executeQuery($sql, $params, $types);
+    }
+
+    /**
+     * Gets the SELECT SQL to select one or more entities by a set of field criteria.
+     *
+     * @param array $criteria
+     * @param AssociationMapping $assoc
+     * @param string $orderBy
+     * @param int $lockMode
+     * @param int $limit
+     * @param int $offset
+     * @param array $orderBy
+     * @return string
+     * @todo Refactor: _getSelectSQL(...)
+     */
+    protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null)
+    {
+        $joinSql      = ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) ? $this->_getSelectManyToManyJoinSQL($assoc) : '';
+        $conditionSql = $this->_getSelectConditionSQL($criteria, $assoc);
+
+        $orderBy    = ($assoc !== null && isset($assoc['orderBy'])) ? $assoc['orderBy'] : $orderBy;
+        $orderBySql = $orderBy ? $this->_getOrderBySQL($orderBy, $this->_getSQLTableAlias($this->_class->name)) : '';
+
+        $lockSql = '';
+
+        if ($lockMode == LockMode::PESSIMISTIC_READ) {
+            $lockSql = ' ' . $this->_platform->getReadLockSql();
+        } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
+            $lockSql = ' ' . $this->_platform->getWriteLockSql();
+        }
+
+        $alias = $this->_getSQLTableAlias($this->_class->name);
+
+        if ($filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) {
+            if ($conditionSql) {
+                $conditionSql .= ' AND ';
+            }
+
+            $conditionSql .= $filterSql;
+        }
+
+        return $this->_platform->modifyLimitQuery('SELECT ' . $this->_getSelectColumnListSQL()
+             . $this->_platform->appendLockHint(' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' '
+             . $alias, $lockMode)
+             . $this->_selectJoinSql . $joinSql
+             . ($conditionSql ? ' WHERE ' . $conditionSql : '')
+             . $orderBySql, $limit, $offset)
+             . $lockSql;
+    }
+
+    /**
+     * Gets the ORDER BY SQL snippet for ordered collections.
+     *
+     * @param array $orderBy
+     * @param string $baseTableAlias
+     * @return string
+     */
+    protected final function _getOrderBySQL(array $orderBy, $baseTableAlias)
+    {
+        $orderBySql = '';
+
+        foreach ($orderBy as $fieldName => $orientation) {
+            if ( ! isset($this->_class->fieldMappings[$fieldName])) {
+                throw ORMException::unrecognizedField($fieldName);
+            }
+
+            $orientation = strtoupper(trim($orientation));
+            if ($orientation != 'ASC' && $orientation != 'DESC') {
+                throw ORMException::invalidOrientation($this->_class->name, $fieldName);
+            }
+
+            $tableAlias = isset($this->_class->fieldMappings[$fieldName]['inherited']) ?
+                    $this->_getSQLTableAlias($this->_class->fieldMappings[$fieldName]['inherited'])
+                    : $baseTableAlias;
+
+            $columnName = $this->_class->getQuotedColumnName($fieldName, $this->_platform);
+
+            $orderBySql .= $orderBySql ? ', ' : ' ORDER BY ';
+            $orderBySql .= $tableAlias . '.' . $columnName . ' ' . $orientation;
+        }
+
+        return $orderBySql;
+    }
+
+    /**
+     * Gets the SQL fragment with the list of columns to select when querying for
+     * an entity in this persister.
+     *
+     * Subclasses should override this method to alter or change the select column
+     * list SQL fragment. Note that in the implementation of BasicEntityPersister
+     * the resulting SQL fragment is generated only once and cached in {@link _selectColumnListSql}.
+     * Subclasses may or may not do the same.
+     *
+     * @return string The SQL fragment.
+     * @todo Rename: _getSelectColumnsSQL()
+     */
+    protected function _getSelectColumnListSQL()
+    {
+        if ($this->_selectColumnListSql !== null) {
+            return $this->_selectColumnListSql;
+        }
+
+        $columnList = '';
+        $this->_rsm = new Query\ResultSetMapping();
+        $this->_rsm->addEntityResult($this->_class->name, 'r'); // r for root
+
+        // Add regular columns to select list
+        foreach ($this->_class->fieldNames as $field) {
+            if ($columnList) $columnList .= ', ';
+
+            $columnList .= $this->_getSelectColumnSQL($field, $this->_class);
+        }
+
+        $this->_selectJoinSql = '';
+        $eagerAliasCounter = 0;
+
+        foreach ($this->_class->associationMappings as $assocField => $assoc) {
+            $assocColumnSQL = $this->_getSelectColumnAssociationSQL($assocField, $assoc, $this->_class);
+
+            if ($assocColumnSQL) {
+                if ($columnList) $columnList .= ', ';
+
+                $columnList .= $assocColumnSQL;
+            }
+
+            if ($assoc['type'] & ClassMetadata::TO_ONE && ($assoc['fetch'] == ClassMetadata::FETCH_EAGER || !$assoc['isOwningSide'])) {
+                $eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']);
+
+                if ($eagerEntity->inheritanceType != ClassMetadata::INHERITANCE_TYPE_NONE) {
+                    continue; // now this is why you shouldn't use inheritance
+                }
+
+                $assocAlias = 'e' . ($eagerAliasCounter++);
+                $this->_rsm->addJoinedEntityResult($assoc['targetEntity'], $assocAlias, 'r', $assocField);
+
+                foreach ($eagerEntity->fieldNames AS $field) {
+                    if ($columnList) $columnList .= ', ';
+
+                    $columnList .= $this->_getSelectColumnSQL($field, $eagerEntity, $assocAlias);
+                }
+
+                foreach ($eagerEntity->associationMappings as $assoc2Field => $assoc2) {
+                    $assoc2ColumnSQL = $this->_getSelectColumnAssociationSQL($assoc2Field, $assoc2, $eagerEntity, $assocAlias);
+
+                    if ($assoc2ColumnSQL) {
+                        if ($columnList) $columnList .= ', ';
+                        $columnList .= $assoc2ColumnSQL;
+                    }
+                }
+                $first = true;
+
+                if ($assoc['isOwningSide']) {
+                    $this->_selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($assoc['joinColumns']);
+                    $this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' ' . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) .' ON ';
+
+                    $tableAlias = $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias);
+                    foreach ($assoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) {
+                        if ( ! $first) {
+                            $this->_selectJoinSql .= ' AND ';
+                        }
+                        $this->_selectJoinSql .= $this->_getSQLTableAlias($assoc['sourceEntity']) . '.' . $sourceCol . ' = '
+                                               . $tableAlias . '.' . $targetCol;
+                        $first = false;
+                    }
+
+                    // Add filter SQL
+                    if ($filterSql = $this->generateFilterConditionSQL($eagerEntity, $tableAlias)) {
+                        $this->_selectJoinSql .= ' AND ' . $filterSql;
+                    }
+                } else {
+                    $eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']);
+                    $owningAssoc = $eagerEntity->getAssociationMapping($assoc['mappedBy']);
+
+                    $this->_selectJoinSql .= ' LEFT JOIN';
+                    $this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' '
+                                           . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) . ' ON ';
+
+                    foreach ($owningAssoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) {
+                        if ( ! $first) {
+                            $this->_selectJoinSql .= ' AND ';
+                        }
+
+                        $this->_selectJoinSql .= $this->_getSQLTableAlias($owningAssoc['sourceEntity'], $assocAlias) . '.' . $sourceCol . ' = '
+                                               . $this->_getSQLTableAlias($owningAssoc['targetEntity']) . '.' . $targetCol;
+                        $first = false;
+                    }
+                }
+            }
+        }
+
+        $this->_selectColumnListSql = $columnList;
+
+        return $this->_selectColumnListSql;
+    }
+
+    /**
+     * Gets the SQL join fragment used when selecting entities from an association.
+     *
+     * @param string $field
+     * @param array $assoc
+     * @param ClassMetadata $class
+     * @param string $alias
+     *
+     * @return string
+     */
+    protected function _getSelectColumnAssociationSQL($field, $assoc, ClassMetadata $class, $alias = 'r')
+    {
+        $columnList = '';
+
+        if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
+            foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
+                if ($columnList) $columnList .= ', ';
+
+                $resultColumnName = $this->getSQLColumnAlias($srcColumn);
+                $columnList .= $this->_getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
+                             . '.' . $srcColumn . ' AS ' . $resultColumnName;
+                $this->_rsm->addMetaResult($alias, $resultColumnName, $srcColumn, isset($assoc['id']) && $assoc['id'] === true);
+            }
+        }
+
+        return $columnList;
+    }
+
+    /**
+     * Gets the SQL join fragment used when selecting entities from a
+     * many-to-many association.
+     *
+     * @param ManyToManyMapping $manyToMany
+     * @return string
+     */
+    protected function _getSelectManyToManyJoinSQL(array $manyToMany)
+    {
+        if ($manyToMany['isOwningSide']) {
+            $owningAssoc = $manyToMany;
+            $joinClauses = $manyToMany['relationToTargetKeyColumns'];
+        } else {
+            $owningAssoc = $this->_em->getClassMetadata($manyToMany['targetEntity'])->associationMappings[$manyToMany['mappedBy']];
+            $joinClauses = $owningAssoc['relationToSourceKeyColumns'];
+        }
+
+        $joinTableName = $this->_class->getQuotedJoinTableName($owningAssoc, $this->_platform);
+        $joinSql = '';
+
+        foreach ($joinClauses as $joinTableColumn => $sourceColumn) {
+            if ($joinSql != '') $joinSql .= ' AND ';
+
+            if ($this->_class->containsForeignIdentifier && ! isset($this->_class->fieldNames[$sourceColumn])) {
+                $quotedColumn = $sourceColumn; // join columns cannot be quoted
+            } else {
+                $quotedColumn = $this->_class->getQuotedColumnName($this->_class->fieldNames[$sourceColumn], $this->_platform);
+            }
+
+            $joinSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $quotedColumn . ' = '
+                      . $joinTableName . '.' . $joinTableColumn;
+        }
+
+        return ' INNER JOIN ' . $joinTableName . ' ON ' . $joinSql;
+    }
+
+    /**
+     * Gets the INSERT SQL used by the persister to persist a new entity.
+     *
+     * @return string
+     */
+    protected function _getInsertSQL()
+    {
+        if ($this->_insertSql === null) {
+            $insertSql = '';
+            $columns = $this->_getInsertColumnList();
+
+            if (empty($columns)) {
+                $insertSql = $this->_platform->getEmptyIdentityInsertSQL(
+                    $this->_class->getQuotedTableName($this->_platform),
+                    $this->_class->getQuotedColumnName($this->_class->identifier[0], $this->_platform)
+                );
+            } else {
+                $columns = array_unique($columns);
+
+                $values = array();
+                foreach ($columns AS $column) {
+                    $placeholder = '?';
+
+                    if (isset($this->_columnTypes[$column]) &&
+                        isset($this->_class->fieldNames[$column]) &&
+                        isset($this->_class->fieldMappings[$this->_class->fieldNames[$column]]['requireSQLConversion'])) {
+                        $type = Type::getType($this->_columnTypes[$column]);
+                        $placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
+                    }
+
+                    $values[] = $placeholder;
+                }
+
+                $insertSql = 'INSERT INTO ' . $this->_class->getQuotedTableName($this->_platform)
+                        . ' (' . implode(', ', $columns) . ') VALUES (' . implode(', ', $values) . ')';
+            }
+
+            $this->_insertSql = $insertSql;
+        }
+
+        return $this->_insertSql;
+    }
+
+    /**
+     * Gets the list of columns to put in the INSERT SQL statement.
+     *
+     * Subclasses should override this method to alter or change the list of
+     * columns placed in the INSERT statements used by the persister.
+     *
+     * @return array The list of columns.
+     */
+    protected function _getInsertColumnList()
+    {
+        $columns = array();
+
+        foreach ($this->_class->reflFields as $name => $field) {
+            if ($this->_class->isVersioned && $this->_class->versionField == $name) {
+                continue;
+            }
+
+            if (isset($this->_class->associationMappings[$name])) {
+                $assoc = $this->_class->associationMappings[$name];
+
+                if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
+                    foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) {
+                        $columns[] = $sourceCol;
+                    }
+                }
+            } else if ($this->_class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->_class->identifier[0] != $name) {
+                $columns[] = $this->_class->getQuotedColumnName($name, $this->_platform);
+                $this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
+            }
+        }
+
+        return $columns;
+    }
+
+    /**
+     * Gets the SQL snippet of a qualified column name for the given field name.
+     *
+     * @param string $field The field name.
+     * @param ClassMetadata $class The class that declares this field. The table this class is
+     *                             mapped to must own the column for the given field.
+     * @param string $alias
+     */
+    protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
+    {
+        $sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias)
+             . '.' . $class->getQuotedColumnName($field, $this->_platform);
+        $columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]);
+
+        $this->_rsm->addFieldResult($alias, $columnAlias, $field);
+
+        if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
+            $type = Type::getType($class->getTypeOfField($field));
+            $sql = $type->convertToPHPValueSQL($sql, $this->_platform);
+        }
+
+        return $sql . ' AS ' . $columnAlias;
+    }
+
+    /**
+     * Gets the SQL table alias for the given class name.
+     *
+     * @param string $className
+     * @return string The SQL table alias.
+     * @todo Reconsider. Binding table aliases to class names is not such a good idea.
+     */
+    protected function _getSQLTableAlias($className, $assocName = '')
+    {
+        if ($assocName) {
+            $className .= '#' . $assocName;
+        }
+
+        if (isset($this->_sqlTableAliases[$className])) {
+            return $this->_sqlTableAliases[$className];
+        }
+
+        $tableAlias = 't' . $this->_sqlAliasCounter++;
+
+        $this->_sqlTableAliases[$className] = $tableAlias;
+
+        return $tableAlias;
+    }
+
+    /**
+     * Lock all rows of this entity matching the given criteria with the specified pessimistic lock mode
+     *
+     * @param array $criteria
+     * @param int $lockMode
+     * @return void
+     */
+    public function lock(array $criteria, $lockMode)
+    {
+        $conditionSql = $this->_getSelectConditionSQL($criteria);
+
+        if ($lockMode == LockMode::PESSIMISTIC_READ) {
+            $lockSql = $this->_platform->getReadLockSql();
+        } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
+            $lockSql = $this->_platform->getWriteLockSql();
+        }
+
+        $sql = 'SELECT 1 '
+             . $this->_platform->appendLockHint($this->getLockTablesSql(), $lockMode)
+             . ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql;
+
+        list($params, $types) = $this->expandParameters($criteria);
+
+        $stmt = $this->_conn->executeQuery($sql, $params, $types);
+    }
+
+    /**
+     * Get the FROM and optionally JOIN conditions to lock the entity managed by this persister.
+     *
+     * @return string
+     */
+    protected function getLockTablesSql()
+    {
+        return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' '
+             . $this->_getSQLTableAlias($this->_class->name);
+    }
+
+    /**
+     * Gets the conditional SQL fragment used in the WHERE clause when selecting
+     * entities in this persister.
+     *
+     * Subclasses are supposed to override this method if they intend to change
+     * or alter the criteria by which entities are selected.
+     *
+     * @param array $criteria
+     * @param AssociationMapping $assoc
+     * @return string
+     */
+    protected function _getSelectConditionSQL(array $criteria, $assoc = null)
+    {
+        $conditionSql = '';
+
+        foreach ($criteria as $field => $value) {
+            $conditionSql .= $conditionSql ? ' AND ' : '';
+
+            $placeholder = '?';
+
+            if (isset($this->_class->columnNames[$field])) {
+                $className = (isset($this->_class->fieldMappings[$field]['inherited']))
+                    ? $this->_class->fieldMappings[$field]['inherited']
+                    : $this->_class->name;
+
+                $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
+
+                if (isset($this->_class->fieldMappings[$field]['requireSQLConversion'])) {
+                    $type = Type::getType($this->_class->getTypeOfField($field));
+                    $placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->_platform);
+                }
+            } else if (isset($this->_class->associationMappings[$field])) {
+                if ( ! $this->_class->associationMappings[$field]['isOwningSide']) {
+                    throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field);
+                }
+
+                $className = (isset($this->_class->associationMappings[$field]['inherited']))
+                    ? $this->_class->associationMappings[$field]['inherited']
+                    : $this->_class->name;
+
+                $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->associationMappings[$field]['joinColumns'][0]['name'];
+            } else if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) {
+                // very careless developers could potentially open up this normally hidden api for userland attacks,
+                // therefore checking for spaces and function calls which are not allowed.
+
+                // found a join column condition, not really a "field"
+                $conditionSql .= $field;
+            } else {
+                throw ORMException::unrecognizedField($field);
+            }
+
+            $conditionSql .= (is_array($value)) ? ' IN (?)' : (($value === null) ? ' IS NULL' : ' = ' . $placeholder);
+        }
+        return $conditionSql;
+    }
+
+    /**
+     * Return an array with (sliced or full list) of elements in the specified collection.
+     *
+     * @param array $assoc
+     * @param object $sourceEntity
+     * @param int $offset
+     * @param int $limit
+     * @return array
+     */
+    public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
+    {
+        $stmt = $this->getOneToManyStatement($assoc, $sourceEntity, $offset, $limit);
+
+        return $this->loadArrayFromStatement($assoc, $stmt);
+    }
+
+    /**
+     * Loads a collection of entities in a one-to-many association.
+     *
+     * @param array $assoc
+     * @param object $sourceEntity
+     * @param PersistentCollection $coll The collection to load/fill.
+     * @param int|null $offset
+     * @param int|null $limit
+     */
+    public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
+    {
+        $stmt = $this->getOneToManyStatement($assoc, $sourceEntity);
+
+        return $this->loadCollectionFromStatement($assoc, $stmt, $coll);
+    }
+
+    /**
+     * Build criteria and execute SQL statement to fetch the one to many entities from.
+     *
+     * @param array $assoc
+     * @param object $sourceEntity
+     * @param int|null $offset
+     * @param int|null $limit
+     * @return \Doctrine\DBAL\Statement
+     */
+    private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
+    {
+        $criteria = array();
+        $owningAssoc = $this->_class->associationMappings[$assoc['mappedBy']];
+        $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']);
+
+        $tableAlias = $this->_getSQLTableAlias(isset($owningAssoc['inherited']) ? $owningAssoc['inherited'] : $this->_class->name);
+
+        foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) {
+            if ($sourceClass->containsForeignIdentifier) {
+                $field = $sourceClass->getFieldForColumn($sourceKeyColumn);
+                $value = $sourceClass->reflFields[$field]->getValue($sourceEntity);
+
+                if (isset($sourceClass->associationMappings[$field])) {
+                    $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+                    $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]];
+                }
+
+                $criteria[$tableAlias . "." . $targetKeyColumn] = $value;
+            } else {
+                $criteria[$tableAlias . "." . $targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
+            }
+        }
+
+        $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, 0, $limit, $offset);
+        list($params, $types) = $this->expandParameters($criteria);
+
+        return $this->_conn->executeQuery($sql, $params, $types);
+    }
+
+    /**
+     * Expand the parameters from the given criteria and use the correct binding types if found.
+     *
+     * @param  array $criteria
+     * @return array
+     */
+    private function expandParameters($criteria)
+    {
+        $params = $types = array();
+
+        foreach ($criteria AS $field => $value) {
+            if ($value === null) {
+                continue; // skip null values.
+            }
+
+            $types[]  = $this->getType($field, $value);
+            $params[] = $this->getValue($value);
+        }
+
+        return array($params, $types);
+    }
+
+    /**
+     * Infer field type to be used by parameter type casting.
+     *
+     * @param string $field
+     * @param mixed $value
+     * @return integer
+     */
+    private function getType($field, $value)
+    {
+        switch (true) {
+            case (isset($this->_class->fieldMappings[$field])):
+                $type = $this->_class->fieldMappings[$field]['type'];
+                break;
+
+            case (isset($this->_class->associationMappings[$field])):
+                $assoc = $this->_class->associationMappings[$field];
+
+                if (count($assoc['sourceToTargetKeyColumns']) > 1) {
+                    throw Query\QueryException::associationPathCompositeKeyNotSupported();
+                }
+
+                $targetClass  = $this->_em->getClassMetadata($assoc['targetEntity']);
+                $targetColumn = $assoc['joinColumns'][0]['referencedColumnName'];
+                $type         = null;
+
+                if (isset($targetClass->fieldNames[$targetColumn])) {
+                    $type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
+                }
+
+                break;
+
+            default:
+                $type = null;
+        }
+        if (is_array($value)) {
+            $type = Type::getType( $type )->getBindingType();
+            $type += Connection::ARRAY_PARAM_OFFSET;
+        }
+
+        return $type;
+    }
+
+    /**
+     * Retrieve parameter value
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    private function getValue($value)
+    {
+        if (is_array($value)) {
+            $newValue = array();
+
+            foreach ($value as $itemValue) {
+                $newValue[] = $this->getIndividualValue($itemValue);
+            }
+
+            return $newValue;
+        }
+
+        return $this->getIndividualValue($value);
+    }
+
+    /**
+     * Retrieve an invidiual parameter value
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    private function getIndividualValue($value)
+    {
+        if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
+            if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
+                $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+            } else {
+                $class = $this->_em->getClassMetadata(get_class($value));
+                $idValues = $class->getIdentifierValues($value);
+            }
+
+            $value = $idValues[key($idValues)];
+        }
+
+        return $value;
+    }
+
+    /**
+     * Checks whether the given managed entity exists in the database.
+     *
+     * @param object $entity
+     * @return boolean TRUE if the entity exists in the database, FALSE otherwise.
+     */
+    public function exists($entity, array $extraConditions = array())
+    {
+        $criteria = $this->_class->getIdentifierValues($entity);
+
+        if ( ! $criteria) {
+            return false;
+        }
+
+        if ($extraConditions) {
+            $criteria = array_merge($criteria, $extraConditions);
+        }
+
+        $alias = $this->_getSQLTableAlias($this->_class->name);
+
+        $sql = 'SELECT 1 '
+             . $this->getLockTablesSql()
+             . ' WHERE ' . $this->_getSelectConditionSQL($criteria);
+
+        if ($filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) {
+            $sql .= ' AND ' . $filterSql;
+        }
+
+        list($params, $types) = $this->expandParameters($criteria);
+
+        return (bool) $this->_conn->fetchColumn($sql, $params);
+    }
+
+    /**
+     * Generates the appropriate join SQL for the given join column.
+     *
+     * @param array $joinColumns The join columns definition of an association.
+     * @return string LEFT JOIN if one of the columns is nullable, INNER JOIN otherwise.
+     */
+    protected function getJoinSQLForJoinColumns($joinColumns)
+    {
+        // if one of the join columns is nullable, return left join
+        foreach ($joinColumns as $joinColumn) {
+             if (!isset($joinColumn['nullable']) || $joinColumn['nullable']) {
+                 return 'LEFT JOIN';
+             }
+        }
+
+        return 'INNER JOIN';
+    }
+
+    /**
+     * Gets an SQL column alias for a column name.
+     *
+     * @param string $columnName
+     * @return string
+     */
+    public function getSQLColumnAlias($columnName)
+    {
+        // Trim the column alias to the maximum identifier length of the platform.
+        // If the alias is to long, characters are cut off from the beginning.
+        return $this->_platform->getSQLResultCasing(
+            substr($columnName . $this->_sqlAliasCounter++, -$this->_platform->getMaxIdentifierLength())
+        );
+    }
+
+    /**
+     * Generates the filter SQL for a given entity and table alias.
+     *
+     * @param ClassMetadata $targetEntity Metadata of the target entity.
+     * @param string $targetTableAlias The table alias of the joined/selected table.
+     *
+     * @return string The SQL query part to add to a query.
+     */
+    protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
+    {
+        $filterClauses = array();
+
+        foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) {
+            if ('' !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) {
+                $filterClauses[] = '(' . $filterExpr . ')';
+            }
+        }
+
+        $sql = implode(' AND ', $filterClauses);
+        return $sql ? "(" . $sql . ")" : ""; // Wrap again to avoid "X or Y and FilterConditionSQL"
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ElementCollectionPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ElementCollectionPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ElementCollectionPersister.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+/**
+ * Persister for collections of basic elements / value types.
+ *
+ * @author robo
+ * @todo Implementation once support for collections of basic elements (i.e. strings) is added.
+ */
+abstract class ElementCollectionPersister extends AbstractCollectionPersister
+{
+    //put your code here
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/JoinedSubclassPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/JoinedSubclassPersister.php	(revision 345)
@@ -0,0 +1,487 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\ORMException,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\DBAL\LockMode,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\Query\ResultSetMapping;
+
+/**
+ * The joined subclass persister maps a single entity instance to several tables in the
+ * database as it is defined by the <tt>Class Table Inheritance</tt> strategy.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Alexander <iam.asm89@gmail.com>
+ * @since 2.0
+ * @see http://martinfowler.com/eaaCatalog/classTableInheritance.html
+ */
+class JoinedSubclassPersister extends AbstractEntityInheritancePersister
+{
+    /**
+     * Map that maps column names to the table names that own them.
+     * This is mainly a temporary cache, used during a single request.
+     *
+     * @var array
+     */
+    private $_owningTableMap = array();
+
+    /**
+     * Map of table to quoted table names.
+     *
+     * @var array
+     */
+    private $_quotedTableMap = array();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _getDiscriminatorColumnTableName()
+    {
+        $class = ($this->_class->name !== $this->_class->rootEntityName)
+            ? $this->_em->getClassMetadata($this->_class->rootEntityName)
+            : $this->_class;
+
+        return $class->getTableName();
+    }
+
+    /**
+     * This function finds the ClassMetadata instance in an inheritance hierarchy
+     * that is responsible for enabling versioning.
+     *
+     * @return \Doctrine\ORM\Mapping\ClassMetadata
+     */
+    private function _getVersionedClassMetadata()
+    {
+        if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) {
+            $definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited'];
+
+            return $this->_em->getClassMetadata($definingClassName);
+        }
+
+        return $this->_class;
+    }
+
+    /**
+     * Gets the name of the table that owns the column the given field is mapped to.
+     *
+     * @param string $fieldName
+     * @return string
+     * @override
+     */
+    public function getOwningTable($fieldName)
+    {
+        if (isset($this->_owningTableMap[$fieldName])) {
+            return $this->_owningTableMap[$fieldName];
+        }
+
+        if (isset($this->_class->associationMappings[$fieldName]['inherited'])) {
+            $cm = $this->_em->getClassMetadata($this->_class->associationMappings[$fieldName]['inherited']);
+        } else if (isset($this->_class->fieldMappings[$fieldName]['inherited'])) {
+            $cm = $this->_em->getClassMetadata($this->_class->fieldMappings[$fieldName]['inherited']);
+        } else {
+            $cm = $this->_class;
+        }
+
+        $tableName = $cm->getTableName();
+
+        $this->_owningTableMap[$fieldName] = $tableName;
+        $this->_quotedTableMap[$tableName] = $cm->getQuotedTableName($this->_platform);
+
+        return $tableName;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function executeInserts()
+    {
+        if ( ! $this->_queuedInserts) {
+            return;
+        }
+
+        $postInsertIds = array();
+        $idGen = $this->_class->idGenerator;
+        $isPostInsertId = $idGen->isPostInsertGenerator();
+
+        // Prepare statement for the root table
+        $rootClass     = ($this->_class->name !== $this->_class->rootEntityName) ? $this->_em->getClassMetadata($this->_class->rootEntityName) : $this->_class;
+        $rootPersister = $this->_em->getUnitOfWork()->getEntityPersister($rootClass->name);
+        $rootTableName = $rootClass->getTableName();
+        $rootTableStmt = $this->_conn->prepare($rootPersister->_getInsertSQL());
+
+        // Prepare statements for sub tables.
+        $subTableStmts = array();
+
+        if ($rootClass !== $this->_class) {
+            $subTableStmts[$this->_class->getTableName()] = $this->_conn->prepare($this->_getInsertSQL());
+        }
+
+        foreach ($this->_class->parentClasses as $parentClassName) {
+            $parentClass = $this->_em->getClassMetadata($parentClassName);
+            $parentTableName = $parentClass->getTableName();
+
+            if ($parentClass !== $rootClass) {
+                $parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName);
+                $subTableStmts[$parentTableName] = $this->_conn->prepare($parentPersister->_getInsertSQL());
+            }
+        }
+
+        // Execute all inserts. For each entity:
+        // 1) Insert on root table
+        // 2) Insert on sub tables
+        foreach ($this->_queuedInserts as $entity) {
+            $insertData = $this->_prepareInsertData($entity);
+
+            // Execute insert on root table
+            $paramIndex = 1;
+
+            foreach ($insertData[$rootTableName] as $columnName => $value) {
+                $rootTableStmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
+            }
+
+            $rootTableStmt->execute();
+
+            if ($isPostInsertId) {
+                $id = $idGen->generate($this->_em, $entity);
+                $postInsertIds[$id] = $entity;
+            } else {
+                $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+            }
+
+            // Execute inserts on subtables.
+            // The order doesn't matter because all child tables link to the root table via FK.
+            foreach ($subTableStmts as $tableName => $stmt) {
+                $data = isset($insertData[$tableName]) ? $insertData[$tableName] : array();
+                $paramIndex = 1;
+
+                foreach ((array) $id as $idName => $idVal) {
+                    $type = isset($this->_columnTypes[$idName]) ? $this->_columnTypes[$idName] : Type::STRING;
+
+                    $stmt->bindValue($paramIndex++, $idVal, $type);
+                }
+
+                foreach ($data as $columnName => $value) {
+                    $stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
+                }
+
+                $stmt->execute();
+            }
+        }
+
+        $rootTableStmt->closeCursor();
+
+        foreach ($subTableStmts as $stmt) {
+            $stmt->closeCursor();
+        }
+
+        if ($this->_class->isVersioned) {
+            $this->assignDefaultVersionValue($entity, $id);
+        }
+
+        $this->_queuedInserts = array();
+
+        return $postInsertIds;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update($entity)
+    {
+        $updateData = $this->_prepareUpdateData($entity);
+
+        if (($isVersioned = $this->_class->isVersioned) != false) {
+            $versionedClass = $this->_getVersionedClassMetadata();
+            $versionedTable = $versionedClass->getTableName();
+        }
+
+        if ($updateData) {
+            foreach ($updateData as $tableName => $data) {
+                $this->_updateTable(
+                    $entity, $this->_quotedTableMap[$tableName], $data, $isVersioned && $versionedTable == $tableName
+                );
+            }
+
+            // Make sure the table with the version column is updated even if no columns on that
+            // table were affected.
+            if ($isVersioned && ! isset($updateData[$versionedTable])) {
+                $this->_updateTable($entity, $versionedClass->getQuotedTableName($this->_platform), array(), true);
+
+                $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+                $this->assignDefaultVersionValue($entity, $id);
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($entity)
+    {
+        $identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
+        $this->deleteJoinTableRecords($identifier);
+
+        $id = array_combine($this->_class->getIdentifierColumnNames(), $identifier);
+
+        // If the database platform supports FKs, just
+        // delete the row from the root table. Cascades do the rest.
+        if ($this->_platform->supportsForeignKeyConstraints()) {
+            $this->_conn->delete(
+                $this->_em->getClassMetadata($this->_class->rootEntityName)->getQuotedTableName($this->_platform), $id
+            );
+        } else {
+            // Delete from all tables individually, starting from this class' table up to the root table.
+            $this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id);
+
+            foreach ($this->_class->parentClasses as $parentClass) {
+                $this->_conn->delete(
+                    $this->_em->getClassMetadata($parentClass)->getQuotedTableName($this->_platform), $id
+                );
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null)
+    {
+        $idColumns = $this->_class->getIdentifierColumnNames();
+        $baseTableAlias = $this->_getSQLTableAlias($this->_class->name);
+
+        // Create the column list fragment only once
+        if ($this->_selectColumnListSql === null) {
+
+            $this->_rsm = new ResultSetMapping();
+            $this->_rsm->addEntityResult($this->_class->name, 'r');
+
+            // Add regular columns
+            $columnList = '';
+
+            foreach ($this->_class->fieldMappings as $fieldName => $mapping) {
+                if ($columnList != '') $columnList .= ', ';
+
+                $columnList .= $this->_getSelectColumnSQL(
+                    $fieldName,
+                    isset($mapping['inherited']) ? $this->_em->getClassMetadata($mapping['inherited']) : $this->_class
+                );
+            }
+
+            // Add foreign key columns
+            foreach ($this->_class->associationMappings as $assoc2) {
+                if ($assoc2['isOwningSide'] && $assoc2['type'] & ClassMetadata::TO_ONE) {
+                    $tableAlias = isset($assoc2['inherited']) ? $this->_getSQLTableAlias($assoc2['inherited']) : $baseTableAlias;
+
+                    foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) {
+                        if ($columnList != '') $columnList .= ', ';
+
+                        $columnList .= $this->getSelectJoinColumnSQL(
+                            $tableAlias,
+                            $srcColumn,
+                            isset($assoc2['inherited']) ? $assoc2['inherited'] : $this->_class->name
+                        );
+                    }
+                }
+            }
+
+            // Add discriminator column (DO NOT ALIAS, see AbstractEntityInheritancePersister#_processSQLResult).
+            $discrColumn = $this->_class->discriminatorColumn['name'];
+            $tableAlias  = ($this->_class->rootEntityName == $this->_class->name) ? $baseTableAlias : $this->_getSQLTableAlias($this->_class->rootEntityName);
+            $columnList .= ', ' . $tableAlias . '.' . $discrColumn;
+
+            $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn);
+
+            $this->_rsm->setDiscriminatorColumn('r', $resultColumnName);
+            $this->_rsm->addMetaResult('r', $resultColumnName, $discrColumn);
+        }
+
+        // INNER JOIN parent tables
+        $joinSql = '';
+
+        foreach ($this->_class->parentClasses as $parentClassName) {
+            $parentClass = $this->_em->getClassMetadata($parentClassName);
+            $tableAlias = $this->_getSQLTableAlias($parentClassName);
+            $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+            $first = true;
+
+            foreach ($idColumns as $idColumn) {
+                if ($first) $first = false; else $joinSql .= ' AND ';
+
+                $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+            }
+        }
+
+        // OUTER JOIN sub tables
+        foreach ($this->_class->subClasses as $subClassName) {
+            $subClass = $this->_em->getClassMetadata($subClassName);
+            $tableAlias = $this->_getSQLTableAlias($subClassName);
+
+            if ($this->_selectColumnListSql === null) {
+                // Add subclass columns
+                foreach ($subClass->fieldMappings as $fieldName => $mapping) {
+                    if (isset($mapping['inherited'])) continue;
+
+                    $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass);
+                }
+
+                // Add join columns (foreign keys)
+                foreach ($subClass->associationMappings as $assoc2) {
+                    if ($assoc2['isOwningSide'] && $assoc2['type'] & ClassMetadata::TO_ONE && ! isset($assoc2['inherited'])) {
+                        foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) {
+                            if ($columnList != '') $columnList .= ', ';
+
+                            $columnList .= $this->getSelectJoinColumnSQL(
+                                $tableAlias,
+                                $srcColumn,
+                                isset($assoc2['inherited']) ? $assoc2['inherited'] : $subClass->name
+                            );
+                        }
+                    }
+                }
+            }
+
+            // Add LEFT JOIN
+            $joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+            $first = true;
+
+            foreach ($idColumns as $idColumn) {
+                if ($first) $first = false; else $joinSql .= ' AND ';
+
+                $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+            }
+        }
+
+        $joinSql .= ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) ? $this->_getSelectManyToManyJoinSQL($assoc) : '';
+
+        $conditionSql = $this->_getSelectConditionSQL($criteria, $assoc);
+
+        // If the current class in the root entity, add the filters
+        if ($filterSql = $this->generateFilterConditionSQL($this->_em->getClassMetadata($this->_class->rootEntityName), $this->_getSQLTableAlias($this->_class->rootEntityName))) {
+            if ($conditionSql) {
+                $conditionSql .= ' AND ';
+            }
+
+            $conditionSql .= $filterSql;
+        }
+
+        $orderBy = ($assoc !== null && isset($assoc['orderBy'])) ? $assoc['orderBy'] : $orderBy;
+        $orderBySql = $orderBy ? $this->_getOrderBySQL($orderBy, $baseTableAlias) : '';
+
+        if ($this->_selectColumnListSql === null) {
+            $this->_selectColumnListSql = $columnList;
+        }
+
+        $lockSql = '';
+
+        if ($lockMode == LockMode::PESSIMISTIC_READ) {
+            $lockSql = ' ' . $this->_platform->getReadLockSql();
+        } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
+            $lockSql = ' ' . $this->_platform->getWriteLockSql();
+        }
+
+        return $this->_platform->modifyLimitQuery('SELECT ' . $this->_selectColumnListSql
+                . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
+                . $joinSql
+                . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql, $limit, $offset)
+                . $lockSql;
+    }
+
+    /**
+     * Get the FROM and optionally JOIN conditions to lock the entity managed by this persister.
+     *
+     * @return string
+     */
+    public function getLockTablesSql()
+    {
+        $idColumns = $this->_class->getIdentifierColumnNames();
+        $baseTableAlias = $this->_getSQLTableAlias($this->_class->name);
+
+        // INNER JOIN parent tables
+        $joinSql = '';
+
+        foreach ($this->_class->parentClasses as $parentClassName) {
+            $parentClass = $this->_em->getClassMetadata($parentClassName);
+            $tableAlias = $this->_getSQLTableAlias($parentClassName);
+            $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+            $first = true;
+
+            foreach ($idColumns as $idColumn) {
+                if ($first) $first = false; else $joinSql .= ' AND ';
+
+                $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+            }
+        }
+
+        return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias . $joinSql;
+    }
+
+    /* Ensure this method is never called. This persister overrides _getSelectEntitiesSQL directly. */
+    protected function _getSelectColumnListSQL()
+    {
+        throw new \BadMethodCallException("Illegal invocation of ".__METHOD__.".");
+    }
+
+    /** {@inheritdoc} */
+    protected function _getInsertColumnList()
+    {
+        // Identifier columns must always come first in the column list of subclasses.
+        $columns = $this->_class->parentClasses ? $this->_class->getIdentifierColumnNames() : array();
+
+        foreach ($this->_class->reflFields as $name => $field) {
+            if (isset($this->_class->fieldMappings[$name]['inherited']) && ! isset($this->_class->fieldMappings[$name]['id'])
+                    || isset($this->_class->associationMappings[$name]['inherited'])
+                    || ($this->_class->isVersioned && $this->_class->versionField == $name)) {
+                continue;
+            }
+
+            if (isset($this->_class->associationMappings[$name])) {
+                $assoc = $this->_class->associationMappings[$name];
+                if ($assoc['type'] & ClassMetadata::TO_ONE && $assoc['isOwningSide']) {
+                    foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) {
+                        $columns[] = $sourceCol;
+                    }
+                }
+            } else if ($this->_class->name != $this->_class->rootEntityName ||
+                    ! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
+                $columns[] = $this->_class->getQuotedColumnName($name, $this->_platform);
+            }
+        }
+
+        // Add discriminator column if it is the topmost class.
+        if ($this->_class->name == $this->_class->rootEntityName) {
+            $columns[] = $this->_class->discriminatorColumn['name'];
+        }
+
+        return $columns;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function assignDefaultVersionValue($entity, $id)
+    {
+        $value = $this->fetchVersionValue($this->_getVersionedClassMetadata(), $id);
+        $this->_class->setFieldValue($entity, $this->_class->versionField, $value);
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ManyToManyPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ManyToManyPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/ManyToManyPersister.php	(revision 345)
@@ -0,0 +1,425 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\PersistentCollection,
+    Doctrine\ORM\UnitOfWork;
+
+/**
+ * Persister for many-to-many collections.
+ *
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Alexander <iam.asm89@gmail.com>
+ * @since   2.0
+ */
+class ManyToManyPersister extends AbstractCollectionPersister
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     */
+    protected function _getDeleteRowSQL(PersistentCollection $coll)
+    {
+        $mapping = $coll->getMapping();
+        $class   = $this->_em->getClassMetadata(get_class($coll->getOwner()));
+
+        return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
+             . ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     * @internal Order of the parameters must be the same as the order of the columns in
+     *           _getDeleteRowSql.
+     */
+    protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
+    {
+        return $this->_collectJoinTableColumnParameters($coll, $element);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     */
+    protected function _getUpdateRowSQL(PersistentCollection $coll)
+    {}
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     * @internal Order of the parameters must be the same as the order of the columns in
+     *           _getInsertRowSql.
+     */
+    protected function _getInsertRowSQL(PersistentCollection $coll)
+    {
+        $mapping = $coll->getMapping();
+        $columns = $mapping['joinTableColumns'];
+        $class   = $this->_em->getClassMetadata(get_class($coll->getOwner()));
+
+        $joinTable = $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform());
+
+        return 'INSERT INTO ' . $joinTable . ' (' . implode(', ', $columns) . ')'
+             . ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     * @internal Order of the parameters must be the same as the order of the columns in
+     *           _getInsertRowSql.
+     */
+    protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
+    {
+        return $this->_collectJoinTableColumnParameters($coll, $element);
+    }
+
+    /**
+     * Collects the parameters for inserting/deleting on the join table in the order
+     * of the join table columns as specified in ManyToManyMapping#joinTableColumns.
+     *
+     * @param $coll
+     * @param $element
+     * @return array
+     */
+    private function _collectJoinTableColumnParameters(PersistentCollection $coll, $element)
+    {
+        $params      = array();
+        $mapping     = $coll->getMapping();
+        $isComposite = count($mapping['joinTableColumns']) > 2;
+
+        $identifier1 = $this->_uow->getEntityIdentifier($coll->getOwner());
+        $identifier2 = $this->_uow->getEntityIdentifier($element);
+
+        if ($isComposite) {
+            $class1 = $this->_em->getClassMetadata(get_class($coll->getOwner()));
+            $class2 = $coll->getTypeClass();
+        }
+
+        foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
+            $isRelationToSource = isset($mapping['relationToSourceKeyColumns'][$joinTableColumn]);
+
+            if ( ! $isComposite) {
+                $params[] = $isRelationToSource ? array_pop($identifier1) : array_pop($identifier2);
+
+                continue;
+            }
+
+            if ($isRelationToSource) {
+                $params[] = $identifier1[$class1->getFieldForColumn($mapping['relationToSourceKeyColumns'][$joinTableColumn])];
+
+                continue;
+            }
+
+            $params[] = $identifier2[$class2->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])];
+        }
+
+        return $params;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     */
+    protected function _getDeleteSQL(PersistentCollection $coll)
+    {
+        $class   = $this->_em->getClassMetadata(get_class($coll->getOwner()));
+        $mapping = $coll->getMapping();
+
+        return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
+             . ' WHERE ' . implode(' = ? AND ', array_keys($mapping['relationToSourceKeyColumns'])) . ' = ?';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @override
+     * @internal Order of the parameters must be the same as the order of the columns in
+     *           _getDeleteSql.
+     */
+    protected function _getDeleteSQLParameters(PersistentCollection $coll)
+    {
+        $identifier = $this->_uow->getEntityIdentifier($coll->getOwner());
+        $mapping    = $coll->getMapping();
+        $params     = array();
+
+        // Optimization for single column identifier
+        if (count($mapping['relationToSourceKeyColumns']) === 1) {
+            $params[] = array_pop($identifier);
+
+            return $params;
+        }
+
+        // Composite identifier
+        $sourceClass = $this->_em->getClassMetadata(get_class($coll->getOwner()));
+
+        foreach ($mapping['relationToSourceKeyColumns'] as $relColumn => $srcColumn) {
+            $params[] = $identifier[$sourceClass->fieldNames[$srcColumn]];
+        }
+
+        return $params;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count(PersistentCollection $coll)
+    {
+        $mapping = $filterMapping = $coll->getMapping();
+        $class   = $this->_em->getClassMetadata($mapping['sourceEntity']);
+        $id      = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner());
+
+        if ($mapping['isOwningSide']) {
+            $joinColumns = $mapping['relationToSourceKeyColumns'];
+        } else {
+            $mapping = $this->_em->getClassMetadata($mapping['targetEntity'])->associationMappings[$mapping['mappedBy']];
+            $joinColumns = $mapping['relationToTargetKeyColumns'];
+        }
+
+        $whereClauses = array();
+        $params  = array();
+
+        foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
+            if ( ! isset($joinColumns[$joinTableColumn])) {
+                continue;
+            }
+
+            $whereClauses[] = $joinTableColumn . ' = ?';
+
+            $params[] = ($class->containsForeignIdentifier)
+                ? $id[$class->getFieldForColumn($joinColumns[$joinTableColumn])]
+                : $id[$class->fieldNames[$joinColumns[$joinTableColumn]]];
+        }
+
+        list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
+        if ($filterSql) {
+            $whereClauses[] = $filterSql;
+        }
+
+        $sql = 'SELECT COUNT(*)'
+            . ' FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) . ' t'
+            . $joinTargetEntitySQL
+            . ' WHERE ' . implode(' AND ', $whereClauses);
+
+        return $this->_conn->fetchColumn($sql, $params);
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param int $offset
+     * @param int $length
+     * @return array
+     */
+    public function slice(PersistentCollection $coll, $offset, $length = null)
+    {
+        $mapping = $coll->getMapping();
+
+        return $this->_em->getUnitOfWork()->getEntityPersister($mapping['targetEntity'])->getManyToManyCollection($mapping, $coll->getOwner(), $offset, $length);
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param object $element
+     * @return boolean
+     */
+    public function contains(PersistentCollection $coll, $element)
+    {
+        $uow = $this->_em->getUnitOfWork();
+
+        // Shortcut for new entities
+        $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
+
+        if ($entityState === UnitOfWork::STATE_NEW) {
+            return false;
+        }
+
+        // Entity is scheduled for inclusion
+        if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
+            return false;
+        }
+
+        list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($coll, $element, true);
+
+        $sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
+
+        return (bool) $this->_conn->fetchColumn($sql, $params);
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param object $element
+     * @return boolean
+     */
+    public function removeElement(PersistentCollection $coll, $element)
+    {
+        $uow = $this->_em->getUnitOfWork();
+
+        // shortcut for new entities
+        $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
+
+        if ($entityState === UnitOfWork::STATE_NEW) {
+            return false;
+        }
+
+        // If Entity is scheduled for inclusion, it is not in this collection.
+        // We can assure that because it would have return true before on array check
+        if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
+            return false;
+        }
+
+        list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($coll, $element, false);
+
+        $sql = 'DELETE FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
+
+        return (bool) $this->_conn->executeUpdate($sql, $params);
+    }
+
+    /**
+     * @param \Doctrine\ORM\PersistentCollection $coll
+     * @param object $element
+     * @param boolean $addFilters Whether the filter SQL should be included or not.
+     * @return array
+     */
+    private function getJoinTableRestrictions(PersistentCollection $coll, $element, $addFilters)
+    {
+        $uow     = $this->_em->getUnitOfWork();
+        $mapping = $filterMapping = $coll->getMapping();
+
+        if ( ! $mapping['isOwningSide']) {
+            $sourceClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+            $targetClass = $this->_em->getClassMetadata($mapping['sourceEntity']);
+            $sourceId = $uow->getEntityIdentifier($element);
+            $targetId = $uow->getEntityIdentifier($coll->getOwner());
+
+            $mapping = $sourceClass->associationMappings[$mapping['mappedBy']];
+        } else {
+            $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']);
+            $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+            $sourceId = $uow->getEntityIdentifier($coll->getOwner());
+            $targetId = $uow->getEntityIdentifier($element);
+        }
+
+        $quotedJoinTable = $sourceClass->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform());
+        $whereClauses    = array();
+        $params          = array();
+
+        foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
+            $whereClauses[] = $joinTableColumn . ' = ?';
+
+            if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) {
+                $params[] = ($targetClass->containsForeignIdentifier)
+                    ? $targetId[$targetClass->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])]
+                    : $targetId[$targetClass->fieldNames[$mapping['relationToTargetKeyColumns'][$joinTableColumn]]];
+                continue;
+            }
+
+            // relationToSourceKeyColumns
+            $params[] = ($sourceClass->containsForeignIdentifier)
+                ? $sourceId[$sourceClass->getFieldForColumn($mapping['relationToSourceKeyColumns'][$joinTableColumn])]
+                : $sourceId[$sourceClass->fieldNames[$mapping['relationToSourceKeyColumns'][$joinTableColumn]]];
+        }
+
+        if ($addFilters) {
+            list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
+            if ($filterSql) {
+                $quotedJoinTable .= ' t ' . $joinTargetEntitySQL;
+                $whereClauses[] = $filterSql;
+            }
+        }
+
+        return array($quotedJoinTable, $whereClauses, $params);
+    }
+
+    /**
+     * Generates the filter SQL for a given mapping.
+     *
+     * This method is not used for actually grabbing the related entities
+     * but when the extra-lazy collection methods are called on a filtered
+     * association. This is why besides the many to many table we also
+     * have to join in the actual entities table leading to additional
+     * JOIN.
+     *
+     * @param array $mapping Array containing mapping information.
+     *
+     * @return string The SQL query part to add to a query.
+     */
+    public function getFilterSql($mapping)
+    {
+        $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+
+        if ($mapping['isOwningSide']) {
+            $joinColumns = $mapping['relationToTargetKeyColumns'];
+        } else {
+            $mapping = $targetClass->associationMappings[$mapping['mappedBy']];
+            $joinColumns = $mapping['relationToSourceKeyColumns'];
+        }
+
+        $targetClass = $this->_em->getClassMetadata($targetClass->rootEntityName);
+
+        // A join is needed if there is filtering on the target entity
+        $joinTargetEntitySQL = '';
+        if ($filterSql = $this->generateFilterConditionSQL($targetClass, 'te')) {
+            $joinTargetEntitySQL = ' JOIN '
+                . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' te'
+                . ' ON';
+
+            $joinTargetEntitySQLClauses = array();
+            foreach ($joinColumns as $joinTableColumn => $targetTableColumn) {
+                $joinTargetEntitySQLClauses[] = ' t.' . $joinTableColumn . ' = ' . 'te.' . $targetTableColumn;
+            }
+
+            $joinTargetEntitySQL .= implode(' AND ', $joinTargetEntitySQLClauses);
+        }
+
+        return array($joinTargetEntitySQL, $filterSql);
+    }
+
+    /**
+     * Generates the filter SQL for a given entity and table alias.
+     *
+     * @param ClassMetadata $targetEntity Metadata of the target entity.
+     * @param string $targetTableAlias The table alias of the joined/selected table.
+     *
+     * @return string The SQL query part to add to a query.
+     */
+    protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
+    {
+        $filterClauses = array();
+
+        foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) {
+            if ($filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) {
+                $filterClauses[] = '(' . $filterExpr . ')';
+            }
+        }
+
+        $sql = implode(' AND ', $filterClauses);
+        return $sql ? "(" . $sql . ")" : "";
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/OneToManyPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/OneToManyPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/OneToManyPersister.php	(revision 345)
@@ -0,0 +1,212 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\PersistentCollection,
+    Doctrine\ORM\UnitOfWork;
+
+/**
+ * Persister for one-to-many collections.
+ *
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Alexander <iam.asm89@gmail.com>
+ * @since   2.0
+ */
+class OneToManyPersister extends AbstractCollectionPersister
+{
+    /**
+     * Generates the SQL UPDATE that updates a particular row's foreign
+     * key to null.
+     *
+     * @param PersistentCollection $coll
+     * @return string
+     * @override
+     */
+    protected function _getDeleteRowSQL(PersistentCollection $coll)
+    {
+        $mapping = $coll->getMapping();
+        $class   = $this->_em->getClassMetadata($mapping['targetEntity']);
+
+        return 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform())
+             . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     */
+    protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
+    {
+        return array_values($this->_uow->getEntityIdentifier($element));
+    }
+
+    protected function _getInsertRowSQL(PersistentCollection $coll)
+    {
+        return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
+    }
+
+    /**
+     * Gets the SQL parameters for the corresponding SQL statement to insert the given
+     * element of the given collection into the database.
+     *
+     * @param PersistentCollection $coll
+     * @param mixed $element
+     */
+    protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
+    {}
+
+    /* Not used for OneToManyPersister */
+    protected function _getUpdateRowSQL(PersistentCollection $coll)
+    {
+        return;
+    }
+
+    /**
+     * Generates the SQL UPDATE that updates all the foreign keys to null.
+     *
+     * @param PersistentCollection $coll
+     */
+    protected function _getDeleteSQL(PersistentCollection $coll)
+    {
+
+    }
+
+    /**
+     * Gets the SQL parameters for the corresponding SQL statement to delete
+     * the given collection.
+     *
+     * @param PersistentCollection $coll
+     */
+    protected function _getDeleteSQLParameters(PersistentCollection $coll)
+    {}
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count(PersistentCollection $coll)
+    {
+        $mapping     = $coll->getMapping();
+        $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+        $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']);
+        $id          = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner());
+
+        $whereClauses = array();
+        $params       = array();
+
+        foreach ($targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] AS $joinColumn) {
+            $whereClauses[] = $joinColumn['name'] . ' = ?';
+
+            $params[] = ($targetClass->containsForeignIdentifier)
+                ? $id[$sourceClass->getFieldForColumn($joinColumn['referencedColumnName'])]
+                : $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]];
+        }
+
+        $filterTargetClass = $this->_em->getClassMetadata($targetClass->rootEntityName);
+        foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) {
+            if ($filterExpr = $filter->addFilterConstraint($filterTargetClass, 't')) {
+                $whereClauses[] = '(' . $filterExpr . ')';
+            }
+        }
+
+        $sql = 'SELECT count(*)'
+             . ' FROM ' . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' t'
+             . ' WHERE ' . implode(' AND ', $whereClauses);
+
+        return $this->_conn->fetchColumn($sql, $params);
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param int $offset
+     * @param int $length
+     * @return \Doctrine\Common\Collections\ArrayCollection
+     */
+    public function slice(PersistentCollection $coll, $offset, $length = null)
+    {
+        $mapping   = $coll->getMapping();
+        $uow       = $this->_em->getUnitOfWork();
+        $persister = $uow->getEntityPersister($mapping['targetEntity']);
+
+        return $persister->getOneToManyCollection($mapping, $coll->getOwner(), $offset, $length);
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param object $element
+     * @return boolean
+     */
+    public function contains(PersistentCollection $coll, $element)
+    {
+        $mapping = $coll->getMapping();
+        $uow     = $this->_em->getUnitOfWork();
+
+        // shortcut for new entities
+        $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
+
+        if ($entityState === UnitOfWork::STATE_NEW) {
+            return false;
+        }
+
+        // Entity is scheduled for inclusion
+        if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
+            return false;
+        }
+
+        $persister = $uow->getEntityPersister($mapping['targetEntity']);
+
+        // only works with single id identifier entities. Will throw an
+        // exception in Entity Persisters if that is not the case for the
+        // 'mappedBy' field.
+        $id = current( $uow->getEntityIdentifier($coll->getOwner()));
+
+        return $persister->exists($element, array($mapping['mappedBy'] => $id));
+    }
+
+    /**
+     * @param PersistentCollection $coll
+     * @param object $element
+     * @return boolean
+     */
+    public function removeElement(PersistentCollection $coll, $element)
+    {
+        $uow = $this->_em->getUnitOfWork();
+
+        // shortcut for new entities
+        $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
+
+        if ($entityState === UnitOfWork::STATE_NEW) {
+            return false;
+        }
+
+        // If Entity is scheduled for inclusion, it is not in this collection.
+        // We can assure that because it would have return true before on array check
+        if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
+            return false;
+        }
+
+        $mapping = $coll->getMapping();
+        $class   = $this->_em->getClassMetadata($mapping['targetEntity']);
+        $sql     = 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform())
+                 . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?';
+
+        return (bool) $this->_conn->executeUpdate($sql, $this->_getDeleteRowSQLParameters($coll, $element));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/SingleTablePersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/SingleTablePersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/SingleTablePersister.php	(revision 345)
@@ -0,0 +1,146 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Persisters;
+
+use Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * Persister for entities that participate in a hierarchy mapped with the
+ * SINGLE_TABLE strategy.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Alexander <iam.asm89@gmail.com>
+ * @since 2.0
+ * @link http://martinfowler.com/eaaCatalog/singleTableInheritance.html
+ */
+class SingleTablePersister extends AbstractEntityInheritancePersister
+{
+    /** {@inheritdoc} */
+    protected function _getDiscriminatorColumnTableName()
+    {
+        return $this->_class->getTableName();
+    }
+
+    /** {@inheritdoc} */
+    protected function _getSelectColumnListSQL()
+    {
+        if ($this->_selectColumnListSql !== null) {
+            return $this->_selectColumnListSql;
+        }
+
+        $columnList = parent::_getSelectColumnListSQL();
+
+        $rootClass  = $this->_em->getClassMetadata($this->_class->rootEntityName);
+        $tableAlias = $this->_getSQLTableAlias($rootClass->name);
+
+         // Append discriminator column
+        $discrColumn = $this->_class->discriminatorColumn['name'];
+        $columnList .= ', ' . $tableAlias . '.' . $discrColumn;
+
+        $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn);
+
+        $this->_rsm->setDiscriminatorColumn('r', $resultColumnName);
+        $this->_rsm->addMetaResult('r', $resultColumnName, $discrColumn);
+
+        // Append subclass columns
+        foreach ($this->_class->subClasses as $subClassName) {
+            $subClass = $this->_em->getClassMetadata($subClassName);
+
+            // Regular columns
+            foreach ($subClass->fieldMappings as $fieldName => $mapping) {
+                if ( ! isset($mapping['inherited'])) {
+                    $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass);
+                }
+            }
+
+            // Foreign key columns
+            foreach ($subClass->associationMappings as $assoc) {
+                if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE && ! isset($assoc['inherited'])) {
+                    foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
+                        if ($columnList != '') $columnList .= ', ';
+
+                        $columnList .= $this->getSelectJoinColumnSQL(
+                            $tableAlias,
+                            $srcColumn,
+                            isset($assoc['inherited']) ? $assoc['inherited'] : $this->_class->name
+                        );
+                    }
+                }
+            }
+        }
+
+        $this->_selectColumnListSql = $columnList;
+        return $this->_selectColumnListSql;
+    }
+
+    /** {@inheritdoc} */
+    protected function _getInsertColumnList()
+    {
+        $columns = parent::_getInsertColumnList();
+
+        // Add discriminator column to the INSERT SQL
+        $columns[] = $this->_class->discriminatorColumn['name'];
+
+        return $columns;
+    }
+
+    /** {@inheritdoc} */
+    protected function _getSQLTableAlias($className, $assocName = '')
+    {
+        return parent::_getSQLTableAlias($this->_class->rootEntityName, $assocName);
+    }
+
+    /** {@inheritdoc} */
+    protected function _getSelectConditionSQL(array $criteria, $assoc = null)
+    {
+        $conditionSql = parent::_getSelectConditionSQL($criteria, $assoc);
+
+        // Append discriminator condition
+        if ($conditionSql) $conditionSql .= ' AND ';
+
+        $values = array();
+
+        if ($this->_class->discriminatorValue !== null) { // discriminators can be 0
+            $values[] = $this->_conn->quote($this->_class->discriminatorValue);
+        }
+
+        $discrValues = array_flip($this->_class->discriminatorMap);
+
+        foreach ($this->_class->subClasses as $subclassName) {
+            $values[] = $this->_conn->quote($discrValues[$subclassName]);
+        }
+
+        $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $this->_class->discriminatorColumn['name']
+                       . ' IN (' . implode(', ', $values) . ')';
+
+        return $conditionSql;
+    }
+
+    /** {@inheritdoc} */
+    protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
+    {
+        // Ensure that the filters are applied to the root entity of the inheritance tree
+        $targetEntity = $this->_em->getClassMetadata($targetEntity->rootEntityName);
+        // we dont care about the $targetTableAlias, in a STI there is only one table.
+
+        return parent::generateFilterConditionSQL($targetEntity, $targetTableAlias);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/UnionSubclassPersister.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/UnionSubclassPersister.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Persisters/UnionSubclassPersister.php	(revision 345)
@@ -0,0 +1,8 @@
+<?php
+
+namespace Doctrine\ORM\Persisters;
+
+class UnionSubclassPersister extends BasicEntityPersister
+{
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PessimisticLockException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PessimisticLockException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/PessimisticLockException.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM;
+
+/**
+ * Pessimistic Lock Exception
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class PessimisticLockException extends ORMException
+{
+    public static function lockFailed()
+    {
+        return new self("The pessimistic lock failed.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Autoloader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Autoloader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Autoloader.php	(revision 345)
@@ -0,0 +1,78 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Proxy;
+
+/**
+ * Special Autoloader for Proxy classes because them not being PSR-0 compatible.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Autoloader
+{
+    /**
+     * Resolve proxy class name to a filename based on the following pattern.
+     *
+     * 1. Remove Proxy namespace from class name
+     * 2. Remove namespace seperators from remaining class name.
+     * 3. Return PHP filename from proxy-dir with the result from 2.
+     *
+     * @param string $proxyDir
+     * @param string $proxyNamespace
+     * @param string $className
+     * @return string
+     */
+    static public function resolveFile($proxyDir, $proxyNamespace, $className)
+    {
+        if (0 !== strpos($className, $proxyNamespace)) {
+            throw ProxyException::notProxyClass($className, $proxyNamespace);
+        }
+
+        $className = str_replace('\\', '', substr($className, strlen($proxyNamespace) +1));
+        return $proxyDir . DIRECTORY_SEPARATOR . $className.'.php';
+    }
+
+    /**
+     * Register and return autoloader callback for the given proxy dir and
+     * namespace.
+     *
+     * @param string $proxyDir
+     * @param string $proxyNamespace
+     * @param Closure $notFoundCallback Invoked when the proxy file is not found.
+     * @return Closure
+     */
+    static public function register($proxyDir, $proxyNamespace, \Closure $notFoundCallback = null)
+    {
+        $proxyNamespace = ltrim($proxyNamespace, "\\");
+        $autoloader = function($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) {
+            if (0 === strpos($className, $proxyNamespace)) {
+                $file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
+
+                if ($notFoundCallback && ! file_exists($file)) {
+                    $notFoundCallback($proxyDir, $proxyNamespace, $className);
+                }
+
+                require $file;
+            }
+        };
+        spl_autoload_register($autoloader);
+        return $autoloader;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Proxy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Proxy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/Proxy.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Proxy;
+
+use Doctrine\Common\Persistence\Proxy as BaseProxy;
+
+/**
+ * Interface for proxy classes.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+interface Proxy extends BaseProxy {}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyException.php	(revision 345)
@@ -0,0 +1,51 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Proxy;
+
+/**
+ * ORM Proxy Exception
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ProxyException extends \Doctrine\ORM\ORMException {
+
+    public static function proxyDirectoryRequired() {
+        return new self("You must configure a proxy directory. See docs for details");
+    }
+
+    public static function proxyNamespaceRequired() {
+        return new self("You must configure a proxy namespace. See docs for details");
+    }
+
+    public static function notProxyClass($className, $proxyNamespace)
+    {
+        return new self(sprintf(
+            "The class %s is not part of the proxy namespace %s",
+            $className, $proxyNamespace
+        ));
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyFactory.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyFactory.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Proxy/ProxyFactory.php	(revision 345)
@@ -0,0 +1,414 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Proxy;
+
+use Doctrine\ORM\EntityManager,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\Common\Util\ClassUtils;
+
+/**
+ * This factory is used to create proxy objects for entities at runtime.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ * @since 2.0
+ */
+class ProxyFactory
+{
+    /** The EntityManager this factory is bound to. */
+    private $_em;
+    /** Whether to automatically (re)generate proxy classes. */
+    private $_autoGenerate;
+    /** The namespace that contains all proxy classes. */
+    private $_proxyNamespace;
+    /** The directory that contains all proxy classes. */
+    private $_proxyDir;
+
+    /**
+     * Used to match very simple id methods that don't need
+     * to be proxied since the identifier is known.
+     *
+     * @var string
+     */
+    const PATTERN_MATCH_ID_METHOD = '((public\s)?(function\s{1,}%s\s?\(\)\s{1,})\s{0,}{\s{0,}return\s{0,}\$this->%s;\s{0,}})i';
+
+    /**
+     * Initializes a new instance of the <tt>ProxyFactory</tt> class that is
+     * connected to the given <tt>EntityManager</tt>.
+     *
+     * @param EntityManager $em The EntityManager the new factory works for.
+     * @param string $proxyDir The directory to use for the proxy classes. It must exist.
+     * @param string $proxyNs The namespace to use for the proxy classes.
+     * @param boolean $autoGenerate Whether to automatically generate proxy classes.
+     */
+    public function __construct(EntityManager $em, $proxyDir, $proxyNs, $autoGenerate = false)
+    {
+        if ( ! $proxyDir) {
+            throw ProxyException::proxyDirectoryRequired();
+        }
+        if ( ! $proxyNs) {
+            throw ProxyException::proxyNamespaceRequired();
+        }
+        $this->_em = $em;
+        $this->_proxyDir = $proxyDir;
+        $this->_autoGenerate = $autoGenerate;
+        $this->_proxyNamespace = $proxyNs;
+    }
+
+    /**
+     * Gets a reference proxy instance for the entity of the given type and identified by
+     * the given identifier.
+     *
+     * @param string $className
+     * @param mixed $identifier
+     * @return object
+     */
+    public function getProxy($className, $identifier)
+    {
+        $fqn = ClassUtils::generateProxyClassName($className, $this->_proxyNamespace);
+
+        if (! class_exists($fqn, false)) {
+            $fileName = $this->getProxyFileName($className);
+            if ($this->_autoGenerate) {
+                $this->_generateProxyClass($this->_em->getClassMetadata($className), $fileName, self::$_proxyClassTemplate);
+            }
+            require $fileName;
+        }
+
+        if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) {
+            $this->_em->getMetadataFactory()->setMetadataFor($fqn, $this->_em->getClassMetadata($className));
+        }
+
+        $entityPersister = $this->_em->getUnitOfWork()->getEntityPersister($className);
+
+        return new $fqn($entityPersister, $identifier);
+    }
+
+    /**
+     * Generate the Proxy file name
+     *
+     * @param string $className
+     * @param string $baseDir Optional base directory for proxy file name generation.
+     *                        If not specified, the directory configured on the Configuration of the
+     *                        EntityManager will be used by this factory.
+     * @return string
+     */
+    private function getProxyFileName($className, $baseDir = null)
+    {
+        $proxyDir = $baseDir ?: $this->_proxyDir;
+
+        return $proxyDir . DIRECTORY_SEPARATOR . '__CG__' . str_replace('\\', '', $className) . '.php';
+    }
+
+    /**
+     * Generates proxy classes for all given classes.
+     *
+     * @param array $classes The classes (ClassMetadata instances) for which to generate proxies.
+     * @param string $toDir The target directory of the proxy classes. If not specified, the
+     *                      directory configured on the Configuration of the EntityManager used
+     *                      by this factory is used.
+     * @return int Number of generated proxies.
+     */
+    public function generateProxyClasses(array $classes, $toDir = null)
+    {
+        $proxyDir = $toDir ?: $this->_proxyDir;
+        $proxyDir = rtrim($proxyDir, DIRECTORY_SEPARATOR);
+        $num = 0;
+
+        foreach ($classes as $class) {
+            /* @var $class ClassMetadata */
+            if ($class->isMappedSuperclass || $class->reflClass->isAbstract()) {
+                continue;
+            }
+
+            $proxyFileName = $this->getProxyFileName($class->name, $proxyDir);
+
+            $this->_generateProxyClass($class, $proxyFileName, self::$_proxyClassTemplate);
+            $num++;
+        }
+
+        return $num;
+    }
+
+    /**
+     * Generates a proxy class file.
+     *
+     * @param $class
+     * @param $proxyClassName
+     * @param $file The path of the file to write to.
+     */
+    private function _generateProxyClass($class, $fileName, $file)
+    {
+        $methods = $this->_generateMethods($class);
+        $sleepImpl = $this->_generateSleep($class);
+        $cloneImpl = $class->reflClass->hasMethod('__clone') ? 'parent::__clone();' : ''; // hasMethod() checks case-insensitive
+
+        $placeholders = array(
+            '<namespace>',
+            '<proxyClassName>', '<className>',
+            '<methods>', '<sleepImpl>', '<cloneImpl>'
+        );
+
+        $className = ltrim($class->name, '\\');
+        $proxyClassName = ClassUtils::generateProxyClassName($class->name, $this->_proxyNamespace);
+        $parts = explode('\\', strrev($proxyClassName), 2);
+        $proxyClassNamespace = strrev($parts[1]);
+        $proxyClassName = strrev($parts[0]);
+
+        $replacements = array(
+            $proxyClassNamespace,
+            $proxyClassName,
+            $className,
+            $methods,
+            $sleepImpl,
+            $cloneImpl
+        );
+
+        $file = str_replace($placeholders, $replacements, $file);
+
+        $parentDirectory = dirname($fileName);
+
+        if ( ! is_dir($parentDirectory)) {
+            if (false === @mkdir($parentDirectory, 0775, true)) {
+                throw ProxyException::proxyDirectoryNotWritable();
+            }
+        } else if ( ! is_writable($parentDirectory)) {
+            throw ProxyException::proxyDirectoryNotWritable();
+        }
+
+        $tmpFileName = $fileName . '.' . uniqid("", true);
+        file_put_contents($tmpFileName, $file);
+        rename($tmpFileName, $fileName);
+    }
+
+    /**
+     * Generates the methods of a proxy class.
+     *
+     * @param ClassMetadata $class
+     * @return string The code of the generated methods.
+     */
+    private function _generateMethods(ClassMetadata $class)
+    {
+        $methods = '';
+
+        $methodNames = array();
+        foreach ($class->reflClass->getMethods() as $method) {
+            /* @var $method ReflectionMethod */
+            if ($method->isConstructor() || in_array(strtolower($method->getName()), array("__sleep", "__clone")) || isset($methodNames[$method->getName()])) {
+                continue;
+            }
+            $methodNames[$method->getName()] = true;
+
+            if ($method->isPublic() && ! $method->isFinal() && ! $method->isStatic()) {
+                $methods .= "\n" . '    public function ';
+                if ($method->returnsReference()) {
+                    $methods .= '&';
+                }
+                $methods .= $method->getName() . '(';
+                $firstParam = true;
+                $parameterString = $argumentString = '';
+
+                foreach ($method->getParameters() as $param) {
+                    if ($firstParam) {
+                        $firstParam = false;
+                    } else {
+                        $parameterString .= ', ';
+                        $argumentString  .= ', ';
+                    }
+
+                    // We need to pick the type hint class too
+                    if (($paramClass = $param->getClass()) !== null) {
+                        $parameterString .= '\\' . $paramClass->getName() . ' ';
+                    } else if ($param->isArray()) {
+                        $parameterString .= 'array ';
+                    }
+
+                    if ($param->isPassedByReference()) {
+                        $parameterString .= '&';
+                    }
+
+                    $parameterString .= '$' . $param->getName();
+                    $argumentString  .= '$' . $param->getName();
+
+                    if ($param->isDefaultValueAvailable()) {
+                        $parameterString .= ' = ' . var_export($param->getDefaultValue(), true);
+                    }
+                }
+
+                $methods .= $parameterString . ')';
+                $methods .= "\n" . '    {' . "\n";
+                if ($this->isShortIdentifierGetter($method, $class)) {
+                    $identifier = lcfirst(substr($method->getName(), 3));
+
+                    $cast = in_array($class->fieldMappings[$identifier]['type'], array('integer', 'smallint')) ? '(int) ' : '';
+
+                    $methods .= '        if ($this->__isInitialized__ === false) {' . "\n";
+                    $methods .= '            return ' . $cast . '$this->_identifier["' . $identifier . '"];' . "\n";
+                    $methods .= '        }' . "\n";
+                }
+                $methods .= '        $this->__load();' . "\n";
+                $methods .= '        return parent::' . $method->getName() . '(' . $argumentString . ');';
+                $methods .= "\n" . '    }' . "\n";
+            }
+        }
+
+        return $methods;
+    }
+
+    /**
+     * Check if the method is a short identifier getter.
+     *
+     * What does this mean? For proxy objects the identifier is already known,
+     * however accessing the getter for this identifier usually triggers the
+     * lazy loading, leading to a query that may not be necessary if only the
+     * ID is interesting for the userland code (for example in views that
+     * generate links to the entity, but do not display anything else).
+     *
+     * @param ReflectionMethod $method
+     * @param ClassMetadata $class
+     * @return bool
+     */
+    private function isShortIdentifierGetter($method, $class)
+    {
+        $identifier = lcfirst(substr($method->getName(), 3));
+        $cheapCheck = (
+            $method->getNumberOfParameters() == 0 &&
+            substr($method->getName(), 0, 3) == "get" &&
+            in_array($identifier, $class->identifier, true) &&
+            $class->hasField($identifier) &&
+            (($method->getEndLine() - $method->getStartLine()) <= 4)
+            && in_array($class->fieldMappings[$identifier]['type'], array('integer', 'bigint', 'smallint', 'string'))
+        );
+
+        if ($cheapCheck) {
+            $code = file($method->getDeclaringClass()->getFileName());
+            $code = trim(implode(" ", array_slice($code, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1)));
+
+            $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier);
+
+            if (preg_match($pattern, $code)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Generates the code for the __sleep method for a proxy class.
+     *
+     * @param $class
+     * @return string
+     */
+    private function _generateSleep(ClassMetadata $class)
+    {
+        $sleepImpl = '';
+
+        if ($class->reflClass->hasMethod('__sleep')) {
+            $sleepImpl .= "return array_merge(array('__isInitialized__'), parent::__sleep());";
+        } else {
+            $sleepImpl .= "return array('__isInitialized__', ";
+            $first = true;
+
+            foreach ($class->getReflectionProperties() as $name => $prop) {
+                if ($first) {
+                    $first = false;
+                } else {
+                    $sleepImpl .= ', ';
+                }
+
+                $sleepImpl .= "'" . $name . "'";
+            }
+
+            $sleepImpl .= ');';
+        }
+
+        return $sleepImpl;
+    }
+
+    /** Proxy class code template */
+    private static $_proxyClassTemplate =
+'<?php
+
+namespace <namespace>;
+
+/**
+ * THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
+ */
+class <proxyClassName> extends \<className> implements \Doctrine\ORM\Proxy\Proxy
+{
+    private $_entityPersister;
+    private $_identifier;
+    public $__isInitialized__ = false;
+    public function __construct($entityPersister, $identifier)
+    {
+        $this->_entityPersister = $entityPersister;
+        $this->_identifier = $identifier;
+    }
+    /** @private */
+    public function __load()
+    {
+        if (!$this->__isInitialized__ && $this->_entityPersister) {
+            $this->__isInitialized__ = true;
+
+            if (method_exists($this, "__wakeup")) {
+                // call this after __isInitialized__to avoid infinite recursion
+                // but before loading to emulate what ClassMetadata::newInstance()
+                // provides.
+                $this->__wakeup();
+            }
+
+            if ($this->_entityPersister->load($this->_identifier, $this) === null) {
+                throw new \Doctrine\ORM\EntityNotFoundException();
+            }
+            unset($this->_entityPersister, $this->_identifier);
+        }
+    }
+
+    /** @private */
+    public function __isInitialized()
+    {
+        return $this->__isInitialized__;
+    }
+
+    <methods>
+
+    public function __sleep()
+    {
+        <sleepImpl>
+    }
+
+    public function __clone()
+    {
+        if (!$this->__isInitialized__ && $this->_entityPersister) {
+            $this->__isInitialized__ = true;
+            $class = $this->_entityPersister->getClassMetadata();
+            $original = $this->_entityPersister->load($this->_identifier);
+            if ($original === null) {
+                throw new \Doctrine\ORM\EntityNotFoundException();
+            }
+            foreach ($class->reflFields AS $field => $reflProperty) {
+                $reflProperty->setValue($this, $reflProperty->getValue($original));
+            }
+            unset($this->_entityPersister, $this->_identifier);
+        }
+        <cloneImpl>
+    }
+}';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query.php	(revision 345)
@@ -0,0 +1,615 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\DBAL\LockMode,
+    Doctrine\ORM\Query\Parser,
+    Doctrine\ORM\Query\ParserResult,
+    Doctrine\ORM\Query\QueryException;
+
+/**
+ * A Query object represents a DQL query.
+ *
+ * @since   1.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+final class Query extends AbstractQuery
+{
+    /* Query STATES */
+    /**
+     * A query object is in CLEAN state when it has NO unparsed/unprocessed DQL parts.
+     */
+    const STATE_CLEAN  = 1;
+    /**
+     * A query object is in state DIRTY when it has DQL parts that have not yet been
+     * parsed/processed. This is automatically defined as DIRTY when addDqlQueryPart
+     * is called.
+     */
+    const STATE_DIRTY = 2;
+
+    /* Query HINTS */
+    /**
+     * The refresh hint turns any query into a refresh query with the result that
+     * any local changes in entities are overridden with the fetched values.
+     *
+     * @var string
+     */
+    const HINT_REFRESH = 'doctrine.refresh';
+
+
+    /**
+     * Internal hint: is set to the proxy entity that is currently triggered for loading
+     *
+     * @var string
+     */
+    const HINT_REFRESH_ENTITY = 'doctrine.refresh.entity';
+
+    /**
+     * The forcePartialLoad query hint forces a particular query to return
+     * partial objects.
+     *
+     * @var string
+     * @todo Rename: HINT_OPTIMIZE
+     */
+    const HINT_FORCE_PARTIAL_LOAD = 'doctrine.forcePartialLoad';
+    /**
+     * The includeMetaColumns query hint causes meta columns like foreign keys and
+     * discriminator columns to be selected and returned as part of the query result.
+     *
+     * This hint does only apply to non-object queries.
+     *
+     * @var string
+     */
+    const HINT_INCLUDE_META_COLUMNS = 'doctrine.includeMetaColumns';
+
+    /**
+     * An array of class names that implement \Doctrine\ORM\Query\TreeWalker and
+     * are iterated and executed after the DQL has been parsed into an AST.
+     *
+     * @var string
+     */
+    const HINT_CUSTOM_TREE_WALKERS = 'doctrine.customTreeWalkers';
+
+    /**
+     * A string with a class name that implements \Doctrine\ORM\Query\TreeWalker
+     * and is used for generating the target SQL from any DQL AST tree.
+     *
+     * @var string
+     */
+    const HINT_CUSTOM_OUTPUT_WALKER = 'doctrine.customOutputWalker';
+
+    //const HINT_READ_ONLY = 'doctrine.readOnly';
+
+    /**
+     * @var string
+     */
+    const HINT_INTERNAL_ITERATION = 'doctrine.internal.iteration';
+
+    /**
+     * @var string
+     */
+    const HINT_LOCK_MODE = 'doctrine.lockMode';
+
+    /**
+     * @var integer $_state   The current state of this query.
+     */
+    private $_state = self::STATE_CLEAN;
+
+    /**
+     * @var string $_dql Cached DQL query.
+     */
+    private $_dql = null;
+
+    /**
+     * @var \Doctrine\ORM\Query\ParserResult  The parser result that holds DQL => SQL information.
+     */
+    private $_parserResult;
+
+    /**
+     * @var integer The first result to return (the "offset").
+     */
+    private $_firstResult = null;
+
+    /**
+     * @var integer The maximum number of results to return (the "limit").
+     */
+    private $_maxResults = null;
+
+    /**
+     * @var CacheDriver The cache driver used for caching queries.
+     */
+    private $_queryCache;
+
+    /**
+     * @var boolean Boolean value that indicates whether or not expire the query cache.
+     */
+    private $_expireQueryCache = false;
+
+    /**
+     * @var int Query Cache lifetime.
+     */
+    private $_queryCacheTTL;
+
+    /**
+     * @var boolean Whether to use a query cache, if available. Defaults to TRUE.
+     */
+    private $_useQueryCache = true;
+
+    // End of Caching Stuff
+
+    /**
+     * Initializes a new Query instance.
+     *
+     * @param \Doctrine\ORM\EntityManager $entityManager
+     */
+    /*public function __construct(EntityManager $entityManager)
+    {
+        parent::__construct($entityManager);
+    }*/
+
+    /**
+     * Gets the SQL query/queries that correspond to this DQL query.
+     *
+     * @return mixed The built sql query or an array of all sql queries.
+     * @override
+     */
+    public function getSQL()
+    {
+        return $this->_parse()->getSQLExecutor()->getSQLStatements();
+    }
+
+    /**
+     * Returns the corresponding AST for this DQL query.
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectStatement |
+     *         \Doctrine\ORM\Query\AST\UpdateStatement |
+     *         \Doctrine\ORM\Query\AST\DeleteStatement
+     */
+    public function getAST()
+    {
+        $parser = new Parser($this);
+        return $parser->getAST();
+    }
+
+    /**
+     * Parses the DQL query, if necessary, and stores the parser result.
+     *
+     * Note: Populates $this->_parserResult as a side-effect.
+     *
+     * @return \Doctrine\ORM\Query\ParserResult
+     */
+    private function _parse()
+    {
+        // Return previous parser result if the query and the filter collection are both clean
+        if ($this->_state === self::STATE_CLEAN
+            && $this->_em->isFiltersStateClean()
+        ) {
+            return $this->_parserResult;
+        }
+
+        $this->_state = self::STATE_CLEAN;
+
+        // Check query cache.
+        if ( ! ($this->_useQueryCache && ($queryCache = $this->getQueryCacheDriver()))) {
+            $parser = new Parser($this);
+            $this->_parserResult = $parser->parse();
+
+            return $this->_parserResult;
+        }
+
+        $hash   = $this->_getQueryCacheId();
+        $cached = $this->_expireQueryCache ? false : $queryCache->fetch($hash);
+
+        if ($cached instanceof ParserResult) {
+            // Cache hit.
+            $this->_parserResult = $cached;
+
+            return $this->_parserResult;
+        }
+
+        // Cache miss.
+        $parser = new Parser($this);
+        $this->_parserResult = $parser->parse();
+        $queryCache->save($hash, $this->_parserResult, $this->_queryCacheTTL);
+
+        return $this->_parserResult;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _doExecute()
+    {
+        $executor = $this->_parse()->getSqlExecutor();
+
+        if ($this->_queryCacheProfile) {
+            $executor->setQueryCacheProfile($this->_queryCacheProfile);
+        }
+
+        // Prepare parameters
+        $paramMappings = $this->_parserResult->getParameterMappings();
+
+        if (count($paramMappings) != count($this->_params)) {
+            throw QueryException::invalidParameterNumber();
+        }
+
+        list($sqlParams, $types) = $this->processParameterMappings($paramMappings);
+
+        if ($this->_resultSetMapping === null) {
+            $this->_resultSetMapping = $this->_parserResult->getResultSetMapping();
+        }
+
+        return $executor->execute($this->_em->getConnection(), $sqlParams, $types);
+    }
+
+    /**
+     * Processes query parameter mappings
+     *
+     * @param array $paramMappings
+     * @return array
+     */
+    private function processParameterMappings($paramMappings)
+    {
+        $sqlParams = $types = array();
+
+        foreach ($this->_params as $key => $value) {
+            if ( ! isset($paramMappings[$key])) {
+                throw QueryException::unknownParameter($key);
+            }
+
+            if (isset($this->_paramTypes[$key])) {
+                foreach ($paramMappings[$key] as $position) {
+                    $types[$position] = $this->_paramTypes[$key];
+                }
+            }
+
+            $sqlPositions = $paramMappings[$key];
+            // optimized multi value sql positions away for now, they are not allowed in DQL anyways.
+            $value = array($value);
+            $countValue = count($value);
+
+            for ($i = 0, $l = count($sqlPositions); $i < $l; $i++) {
+                $sqlParams[$sqlPositions[$i]] = $value[($i % $countValue)];
+            }
+        }
+
+        if (count($sqlParams) != count($types)) {
+            throw QueryException::parameterTypeMissmatch();
+        }
+
+        if ($sqlParams) {
+            ksort($sqlParams);
+            $sqlParams = array_values($sqlParams);
+
+            ksort($types);
+            $types = array_values($types);
+        }
+
+        return array($sqlParams, $types);
+    }
+
+    /**
+     * Defines a cache driver to be used for caching queries.
+     *
+     * @param Doctrine_Cache_Interface|null $driver Cache driver
+     * @return Query This query instance.
+     */
+    public function setQueryCacheDriver($queryCache)
+    {
+        $this->_queryCache = $queryCache;
+
+        return $this;
+    }
+
+    /**
+     * Defines whether the query should make use of a query cache, if available.
+     *
+     * @param boolean $bool
+     * @return @return Query This query instance.
+     */
+    public function useQueryCache($bool)
+    {
+        $this->_useQueryCache = $bool;
+
+        return $this;
+    }
+
+    /**
+     * Returns the cache driver used for query caching.
+     *
+     * @return CacheDriver The cache driver used for query caching or NULL, if this
+     * 					   Query does not use query caching.
+     */
+    public function getQueryCacheDriver()
+    {
+        if ($this->_queryCache) {
+            return $this->_queryCache;
+        }
+
+        return $this->_em->getConfiguration()->getQueryCacheImpl();
+    }
+
+    /**
+     * Defines how long the query cache will be active before expire.
+     *
+     * @param integer $timeToLive How long the cache entry is valid
+     * @return Query This query instance.
+     */
+    public function setQueryCacheLifetime($timeToLive)
+    {
+        if ($timeToLive !== null) {
+            $timeToLive = (int) $timeToLive;
+        }
+
+        $this->_queryCacheTTL = $timeToLive;
+
+        return $this;
+    }
+
+    /**
+     * Retrieves the lifetime of resultset cache.
+     *
+     * @return int
+     */
+    public function getQueryCacheLifetime()
+    {
+        return $this->_queryCacheTTL;
+    }
+
+    /**
+     * Defines if the query cache is active or not.
+     *
+     * @param boolean $expire Whether or not to force query cache expiration.
+     * @return Query This query instance.
+     */
+    public function expireQueryCache($expire = true)
+    {
+        $this->_expireQueryCache = $expire;
+
+        return $this;
+    }
+
+    /**
+     * Retrieves if the query cache is active or not.
+     *
+     * @return bool
+     */
+    public function getExpireQueryCache()
+    {
+        return $this->_expireQueryCache;
+    }
+
+    /**
+     * @override
+     */
+    public function free()
+    {
+        parent::free();
+
+        $this->_dql = null;
+        $this->_state = self::STATE_CLEAN;
+    }
+
+    /**
+     * Sets a DQL query string.
+     *
+     * @param string $dqlQuery DQL Query
+     * @return \Doctrine\ORM\AbstractQuery
+     */
+    public function setDQL($dqlQuery)
+    {
+        if ($dqlQuery !== null) {
+            $this->_dql = $dqlQuery;
+            $this->_state = self::STATE_DIRTY;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns the DQL query that is represented by this query object.
+     *
+     * @return string DQL query
+     */
+    public function getDQL()
+    {
+        return $this->_dql;
+    }
+
+    /**
+     * Returns the state of this query object
+     * By default the type is Doctrine_ORM_Query_Abstract::STATE_CLEAN but if it appears any unprocessed DQL
+     * part, it is switched to Doctrine_ORM_Query_Abstract::STATE_DIRTY.
+     *
+     * @see AbstractQuery::STATE_CLEAN
+     * @see AbstractQuery::STATE_DIRTY
+     *
+     * @return integer Return the query state
+     */
+    public function getState()
+    {
+        return $this->_state;
+    }
+
+    /**
+     * Method to check if an arbitrary piece of DQL exists
+     *
+     * @param string $dql Arbitrary piece of DQL to check for
+     * @return boolean
+     */
+    public function contains($dql)
+    {
+        return stripos($this->getDQL(), $dql) === false ? false : true;
+    }
+
+    /**
+     * Sets the position of the first result to retrieve (the "offset").
+     *
+     * @param integer $firstResult The first result to return.
+     * @return Query This query object.
+     */
+    public function setFirstResult($firstResult)
+    {
+        $this->_firstResult = $firstResult;
+        $this->_state = self::STATE_DIRTY;
+
+        return $this;
+    }
+
+    /**
+     * Gets the position of the first result the query object was set to retrieve (the "offset").
+     * Returns NULL if {@link setFirstResult} was not applied to this query.
+     *
+     * @return integer The position of the first result.
+     */
+    public function getFirstResult()
+    {
+        return $this->_firstResult;
+    }
+
+    /**
+     * Sets the maximum number of results to retrieve (the "limit").
+     *
+     * @param integer $maxResults
+     * @return Query This query object.
+     */
+    public function setMaxResults($maxResults)
+    {
+        $this->_maxResults = $maxResults;
+        $this->_state = self::STATE_DIRTY;
+
+        return $this;
+    }
+
+    /**
+     * Gets the maximum number of results the query object was set to retrieve (the "limit").
+     * Returns NULL if {@link setMaxResults} was not applied to this query.
+     *
+     * @return integer Maximum number of results.
+     */
+    public function getMaxResults()
+    {
+        return $this->_maxResults;
+    }
+
+    /**
+     * Executes the query and returns an IterableResult that can be used to incrementally
+     * iterated over the result.
+     *
+     * @param array $params The query parameters.
+     * @param integer $hydrationMode The hydration mode to use.
+     * @return \Doctrine\ORM\Internal\Hydration\IterableResult
+     */
+    public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
+    {
+        $this->setHint(self::HINT_INTERNAL_ITERATION, true);
+
+        return parent::iterate($params, $hydrationMode);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setHint($name, $value)
+    {
+        $this->_state = self::STATE_DIRTY;
+
+        return parent::setHint($name, $value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setHydrationMode($hydrationMode)
+    {
+        $this->_state = self::STATE_DIRTY;
+
+        return parent::setHydrationMode($hydrationMode);
+    }
+
+    /**
+     * Set the lock mode for this Query.
+     *
+     * @see \Doctrine\DBAL\LockMode
+     * @param  int $lockMode
+     * @return Query
+     */
+    public function setLockMode($lockMode)
+    {
+        if ($lockMode === LockMode::PESSIMISTIC_READ || $lockMode === LockMode::PESSIMISTIC_WRITE) {
+            if ( ! $this->_em->getConnection()->isTransactionActive()) {
+                throw TransactionRequiredException::transactionRequired();
+            }
+        }
+
+        $this->setHint(self::HINT_LOCK_MODE, $lockMode);
+
+        return $this;
+    }
+
+    /**
+     * Get the current lock mode for this query.
+     *
+     * @return int
+     */
+    public function getLockMode()
+    {
+        $lockMode = $this->getHint(self::HINT_LOCK_MODE);
+
+        if ( ! $lockMode) {
+            return LockMode::NONE;
+        }
+
+        return $lockMode;
+    }
+
+    /**
+     * Generate a cache id for the query cache - reusing the Result-Cache-Id generator.
+     *
+     * The query cache
+     *
+     * @return string
+     */
+    protected function _getQueryCacheId()
+    {
+        ksort($this->_hints);
+
+        return md5(
+            $this->getDql() . var_export($this->_hints, true) .
+            ($this->_em->hasFilters() ? $this->_em->getFilters()->getHash() : '') .
+            '&firstResult=' . $this->_firstResult . '&maxResult=' . $this->_maxResults .
+            '&hydrationMode='.$this->_hydrationMode.'DOCTRINE_QUERY_CACHE_SALT'
+        );
+    }
+
+    /**
+     * Cleanup Query resource when clone is called.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        parent::__clone();
+
+        $this->_state = self::STATE_DIRTY;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ASTException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ASTException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ASTException.php	(revision 345)
@@ -0,0 +1,13 @@
+<?php
+
+namespace Doctrine\ORM\Query\AST;
+
+use Doctrine\ORM\Query\QueryException;
+
+class ASTException extends QueryException
+{
+    public static function noDispatchForNode($node)
+    {
+        return new self("Double-dispatch for node " . get_class($node) . " is not supported.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/AggregateExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/AggregateExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/AggregateExpression.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Description of AggregateExpression
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class AggregateExpression extends Node
+{
+    public $functionName;
+    public $pathExpression;
+    public $isDistinct = false; // Some aggregate expressions support distinct, eg COUNT
+
+    public function __construct($functionName, $pathExpression, $isDistinct)
+    {
+        $this->functionName = $functionName;
+        $this->pathExpression = $pathExpression;
+        $this->isDistinct = $isDistinct;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkAggregateExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticExpression.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ArithmeticExpression extends Node
+{
+    public $simpleArithmeticExpression;
+    public $subselect;
+
+    public function isSimpleArithmeticExpression()
+    {
+        return (bool) $this->simpleArithmeticExpression;
+    }
+
+    public function isSubselect()
+    {
+        return (bool) $this->subselect;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkArithmeticExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticFactor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticFactor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticFactor.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ArithmeticFactor extends Node
+{
+    /**
+     * @var ArithmeticPrimary
+     */
+    public $arithmeticPrimary;
+
+    /**
+     * @var null|boolean NULL represents no sign, TRUE means positive and FALSE means negative sign
+     */
+    public $sign;
+
+    public function __construct($arithmeticPrimary, $sign = null)
+    {
+        $this->arithmeticPrimary = $arithmeticPrimary;
+        $this->sign = $sign;
+    }
+
+    public function isPositiveSigned()
+    {
+        return $this->sign === true;
+    }
+
+    public function isNegativeSigned()
+    {
+        return $this->sign === false;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkArithmeticFactor($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticTerm.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticTerm.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ArithmeticTerm.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ArithmeticTerm extends Node
+{
+    public $arithmeticFactors;
+
+    public function __construct(array $arithmeticFactors)
+    {
+        $this->arithmeticFactors = $arithmeticFactors;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkArithmeticTerm($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/BetweenExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/BetweenExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/BetweenExpression.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Description of BetweenExpression
+ *
+  @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class BetweenExpression extends Node
+{
+    public $expression;
+    public $leftBetweenExpression;
+    public $rightBetweenExpression;
+    public $not;
+
+    public function __construct($expr, $leftExpr, $rightExpr)
+    {
+        $this->expression = $expr;
+        $this->leftBetweenExpression = $leftExpr;
+        $this->rightBetweenExpression = $rightExpr;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkBetweenExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CoalesceExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CoalesceExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CoalesceExpression.php	(revision 345)
@@ -0,0 +1,47 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
+ *
+ * @since   2.1
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class CoalesceExpression extends Node
+{
+    public $scalarExpressions = array();
+
+
+    public function __construct(array $scalarExpressions)
+    {
+        $this->scalarExpressions  = $scalarExpressions;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkCoalesceExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CollectionMemberExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CollectionMemberExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/CollectionMemberExpression.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class CollectionMemberExpression extends Node
+{
+    public $entityExpression;
+    public $collectionValuedPathExpression;
+    public $not;
+
+    public function __construct($entityExpr, $collValuedPathExpr)
+    {
+        $this->entityExpression = $entityExpr;
+        $this->collectionValuedPathExpression = $collValuedPathExpr;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkCollectionMemberExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ComparisonExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ComparisonExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ComparisonExpression.php	(revision 345)
@@ -0,0 +1,57 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) |
+ *                          StringExpression ComparisonOperator (StringExpression | QuantifiedExpression) |
+ *                          BooleanExpression ("=" | "<>" | "!=") (BooleanExpression | QuantifiedExpression) |
+ *                          EnumExpression ("=" | "<>" | "!=") (EnumExpression | QuantifiedExpression) |
+ *                          DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) |
+ *                          EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression)
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ComparisonExpression extends Node
+{
+    public $leftExpression;
+    public $rightExpression;
+    public $operator;
+
+    public function __construct($leftExpr, $operator, $rightExpr)
+    {
+        $this->leftExpression = $leftExpr;
+        $this->rightExpression = $rightExpr;
+        $this->operator = $operator;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkComparisonExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalExpression.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConditionalExpression extends Node
+{
+    public $conditionalTerms = array();
+
+    public function __construct(array $conditionalTerms)
+    {
+        $this->conditionalTerms = $conditionalTerms;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkConditionalExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalFactor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalFactor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalFactor.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ConditionalFactor ::= ["NOT"] ConditionalPrimary
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConditionalFactor extends Node
+{
+    public $not = false;
+    public $conditionalPrimary;
+
+    public function __construct($conditionalPrimary)
+    {
+        $this->conditionalPrimary = $conditionalPrimary;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkConditionalFactor($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalPrimary.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalPrimary.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalPrimary.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConditionalPrimary extends Node
+{
+    public $simpleConditionalExpression;
+    public $conditionalExpression;
+
+    public function isSimpleConditionalExpression()
+    {
+        return (bool) $this->simpleConditionalExpression;
+    }
+
+    public function isConditionalExpression()
+    {
+        return (bool) $this->conditionalExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkConditionalPrimary($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalTerm.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalTerm.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ConditionalTerm.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConditionalTerm extends Node
+{
+    public $conditionalFactors = array();
+
+    public function __construct(array $conditionalFactors)
+    {
+        $this->conditionalFactors = $conditionalFactors;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkConditionalTerm($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteClause.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] AliasIdentificationVariable]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class DeleteClause extends Node
+{
+    public $abstractSchemaName;
+    public $aliasIdentificationVariable;
+
+    public function __construct($abstractSchemaName)
+    {
+        $this->abstractSchemaName = $abstractSchemaName;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkDeleteClause($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/DeleteStatement.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * DeleteStatement = DeleteClause [WhereClause]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class DeleteStatement extends Node
+{
+    public $deleteClause;
+    public $whereClause;
+
+    public function __construct($deleteClause)
+    {
+        $this->deleteClause = $deleteClause;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkDeleteStatement($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EmptyCollectionComparisonExpression extends Node
+{
+    public $expression;
+    public $not;
+
+    public function __construct($expression)
+    {
+        $this->expression = $expression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkEmptyCollectionComparisonExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ExistsExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ExistsExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/ExistsExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ExistsExpression extends Node
+{
+    public $not;
+    public $subselect;
+
+    public function __construct($subselect)
+    {
+        $this->subselect = $subselect;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkExistsExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/FromClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/FromClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/FromClause.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class FromClause extends Node
+{
+    public $identificationVariableDeclarations = array();
+
+    public function __construct(array $identificationVariableDeclarations)
+    {
+        $this->identificationVariableDeclarations = $identificationVariableDeclarations;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkFromClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/AbsFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/AbsFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/AbsFunction.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "ABS" "(" SimpleArithmeticExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class AbsFunction extends FunctionNode
+{
+    public $simpleArithmeticExpression;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression(
+            $this->simpleArithmeticExpression
+        ) . ')';
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php	(revision 345)
@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "BIT_AND" "(" ArithmeticPrimary "," ArithmeticPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class BitAndFunction extends FunctionNode
+{
+    public $firstArithmetic;
+    public $secondArithmetic;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $platform = $sqlWalker->getConnection()->getDatabasePlatform();
+        return $platform->getBitAndComparisonExpression(
+            $this->firstArithmetic->dispatch($sqlWalker),
+            $this->secondArithmetic->dispatch($sqlWalker)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstArithmetic = $parser->ArithmeticPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->secondArithmetic = $parser->ArithmeticPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php	(revision 345)
@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "BIT_OR" "(" ArithmeticPrimary "," ArithmeticPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class BitOrFunction extends FunctionNode
+{
+    public $firstArithmetic;
+    public $secondArithmetic;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $platform = $sqlWalker->getConnection()->getDatabasePlatform();
+        return $platform->getBitOrComparisonExpression(
+            $this->firstArithmetic->dispatch($sqlWalker),
+            $this->secondArithmetic->dispatch($sqlWalker)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstArithmetic = $parser->ArithmeticPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->secondArithmetic = $parser->ArithmeticPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "CONCAT" "(" StringPrimary "," StringPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ConcatFunction extends FunctionNode
+{
+    public $firstStringPrimary;
+    public $secondStringPriamry;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $platform = $sqlWalker->getConnection()->getDatabasePlatform();
+        return $platform->getConcatExpression(
+            $sqlWalker->walkStringPrimary($this->firstStringPrimary),
+            $sqlWalker->walkStringPrimary($this->secondStringPrimary)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstStringPrimary = $parser->StringPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->secondStringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "CURRENT_DATE"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class CurrentDateFunction extends FunctionNode
+{
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentDateSQL();
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "CURRENT_TIME"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class CurrentTimeFunction extends FunctionNode
+{
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimeSQL();
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "CURRENT_TIMESTAMP"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class CurrentTimestampFunction extends FunctionNode
+{
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimestampSQL();
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php	(revision 345)
@@ -0,0 +1,71 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+use Doctrine\ORM\Query\QueryException;
+
+/**
+ * "DATE_ADD(date1, interval, unit)"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DateAddFunction extends FunctionNode
+{
+    public $firstDateExpression = null;
+    public $intervalExpression = null;
+    public $unit = null;
+
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        $unit = strtolower($this->unit);
+        if ($unit == "day") {
+            return $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddDaysExpression(
+                $this->firstDateExpression->dispatch($sqlWalker),
+                $this->intervalExpression->dispatch($sqlWalker)
+            );
+        } else if ($unit == "month") {
+            return $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddMonthExpression(
+                $this->firstDateExpression->dispatch($sqlWalker),
+                $this->intervalExpression->dispatch($sqlWalker)
+            );
+        } else {
+            throw QueryException::semanticalError('DATE_ADD() only supports units of type day and month.');
+        }
+    }
+
+    public function parse(Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstDateExpression = $parser->ArithmeticPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->intervalExpression = $parser->ArithmeticPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->unit = $parser->StringPrimary();
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+
+/**
+ * "DATE_DIFF(date1, date2)"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DateDiffFunction extends FunctionNode
+{
+    public $date1;
+    public $date2;
+
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getDateDiffExpression(
+            $this->date1->dispatch($sqlWalker),
+            $this->date2->dispatch($sqlWalker)
+        );
+    }
+
+    public function parse(Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->date1 = $parser->ArithmeticPrimary();
+        $parser->match(Lexer::T_COMMA);
+        $this->date2 = $parser->ArithmeticPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+use Doctrine\ORM\Query\QueryException;
+
+/**
+ * "DATE_ADD(date1, interval, unit)"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DateSubFunction extends DateAddFunction
+{
+    public $firstDateExpression = null;
+    public $intervalExpression = null;
+    public $unit = null;
+
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        $unit = strtolower($this->unit);
+        if ($unit == "day") {
+            return $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubDaysExpression(
+                $this->firstDateExpression->dispatch($sqlWalker),
+                $this->intervalExpression->dispatch($sqlWalker)
+            );
+        } else if ($unit == "month") {
+            return $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubMonthExpression(
+                $this->firstDateExpression->dispatch($sqlWalker),
+                $this->intervalExpression->dispatch($sqlWalker)
+            );
+        } else {
+            throw QueryException::semanticalError('DATE_SUB() only supports units of type day and month.');
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/FunctionNode.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/FunctionNode.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/FunctionNode.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\AST\Node;
+
+/**
+ * Abtract Function Node.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class FunctionNode extends Node
+{
+    public $name;
+
+    public function __construct($name)
+    {
+        $this->name = $name;
+    }
+
+    abstract public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker);
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkFunction($this);
+    }
+
+    abstract public function parse(\Doctrine\ORM\Query\Parser $parser);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "IDENTITY" "(" SingleValuedAssociationPathExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class IdentityFunction extends FunctionNode
+{
+    public $pathExpression;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $platform   = $sqlWalker->getConnection()->getDatabasePlatform();
+        $dqlAlias   = $this->pathExpression->identificationVariable;
+        $assocField = $this->pathExpression->field;
+
+        $qComp = $sqlWalker->getQueryComponent($dqlAlias);
+        $class = $qComp['metadata'];
+        $assoc = $class->associationMappings[$assocField];
+
+        $tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+        return $tableAlias . '.' . reset($assoc['targetToSourceKeyColumns']);;
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->pathExpression = $parser->SingleValuedAssociationPathExpression();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LengthFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LengthFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LengthFunction.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "LENGTH" "(" StringPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LengthFunction extends FunctionNode
+{
+    public $stringPrimary;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getLengthExpression(
+               $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->stringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LocateFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LocateFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LocateFunction.php	(revision 345)
@@ -0,0 +1,81 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LocateFunction extends FunctionNode
+{
+    public $firstStringPrimary;
+    public $secondStringPrimary;
+    public $simpleArithmeticExpression = false;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getLocateExpression(
+            $sqlWalker->walkStringPrimary($this->secondStringPrimary), // its the other way around in platform
+            $sqlWalker->walkStringPrimary($this->firstStringPrimary),
+            (($this->simpleArithmeticExpression)
+                ? $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression)
+                : false
+            )
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstStringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_COMMA);
+
+        $this->secondStringPrimary = $parser->StringPrimary();
+
+        $lexer = $parser->getLexer();
+        if ($lexer->isNextToken(Lexer::T_COMMA)) {
+            $parser->match(Lexer::T_COMMA);
+
+            $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+        }
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LowerFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LowerFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/LowerFunction.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "LOWER" "(" StringPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LowerFunction extends FunctionNode
+{
+    public $stringPrimary;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getLowerExpression(
+               $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->stringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ModFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ModFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/ModFunction.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ModFunction extends FunctionNode
+{
+    public $firstSimpleArithmeticExpression;
+    public $secondSimpleArithmeticExpression;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getModExpression(
+               $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression),
+               $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_MOD);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+
+        $parser->match(Lexer::T_COMMA);
+
+        $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SizeFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SizeFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SizeFunction.php	(revision 345)
@@ -0,0 +1,122 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "SIZE" "(" CollectionValuedPathExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SizeFunction extends FunctionNode
+{
+    public $collectionPathExpression;
+
+    /**
+     * @override
+     * @todo If the collection being counted is already joined, the SQL can be simpler (more efficient).
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $platform = $sqlWalker->getConnection()->getDatabasePlatform();
+        $dqlAlias = $this->collectionPathExpression->identificationVariable;
+        $assocField = $this->collectionPathExpression->field;
+
+        $qComp = $sqlWalker->getQueryComponent($dqlAlias);
+        $class = $qComp['metadata'];
+        $assoc = $class->associationMappings[$assocField];
+        $sql = 'SELECT COUNT(*) FROM ';
+
+        if ($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_MANY) {
+            $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
+            $targetTableAlias = $sqlWalker->getSQLTableAlias($targetClass->getTableName());
+            $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            $sql .= $targetClass->getQuotedTableName($platform) . ' ' . $targetTableAlias . ' WHERE ';
+
+            $owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']];
+
+            $first = true;
+
+            foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) {
+                if ($first) $first = false; else $sql .= ' AND ';
+
+                $sql .= $targetTableAlias . '.' . $sourceColumn
+                      . ' = '
+                      . $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $platform);
+            }
+        } else { // many-to-many
+            $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
+
+            $owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']];
+            $joinTable = $owningAssoc['joinTable'];
+
+            // SQL table aliases
+            $joinTableAlias = $sqlWalker->getSQLTableAlias($joinTable['name']);
+            $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            // join to target table
+            $sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $platform) . ' ' . $joinTableAlias . ' WHERE ';
+
+            $joinColumns = $assoc['isOwningSide']
+                ? $joinTable['joinColumns']
+                : $joinTable['inverseJoinColumns'];
+
+            $first = true;
+
+            foreach ($joinColumns as $joinColumn) {
+                if ($first) $first = false; else $sql .= ' AND ';
+
+                $sourceColumnName = $class->getQuotedColumnName(
+                    $class->fieldNames[$joinColumn['referencedColumnName']], $platform
+                );
+
+                $sql .= $joinTableAlias . '.' . $joinColumn['name']
+                      . ' = '
+                      . $sourceTableAlias . '.' . $sourceColumnName;
+            }
+        }
+
+        return '(' . $sql . ')';
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $lexer = $parser->getLexer();
+
+        $parser->match(Lexer::T_SIZE);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->collectionPathExpression = $parser->CollectionValuedPathExpression();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php	(revision 345)
@@ -0,0 +1,61 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "SQRT" "(" SimpleArithmeticExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SqrtFunction extends FunctionNode
+{
+    public $simpleArithmeticExpression;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        //TODO: Use platform to get SQL
+        return 'SQRT(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php	(revision 345)
@@ -0,0 +1,82 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SubstringFunction extends FunctionNode
+{
+    public $stringPrimary;
+    public $firstSimpleArithmeticExpression;
+    public $secondSimpleArithmeticExpression = null;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $optionalSecondSimpleArithmeticExpression = null;
+        if ($this->secondSimpleArithmeticExpression !== null) {
+            $optionalSecondSimpleArithmeticExpression = $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression);
+        }
+
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getSubstringExpression(
+            $sqlWalker->walkStringPrimary($this->stringPrimary),
+            $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression),
+            $optionalSecondSimpleArithmeticExpression
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->stringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_COMMA);
+
+        $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+
+        $lexer = $parser->getLexer();
+        if ($lexer->isNextToken(Lexer::T_COMMA)) {
+            $parser->match(Lexer::T_COMMA);
+
+            $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
+        }
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/TrimFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/TrimFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/TrimFunction.php	(revision 345)
@@ -0,0 +1,100 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class TrimFunction extends FunctionNode
+{
+    public $leading;
+    public $trailing;
+    public $both;
+    public $trimChar = false;
+    public $stringPrimary;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        $pos = AbstractPlatform::TRIM_UNSPECIFIED;
+        if ($this->leading) {
+            $pos = AbstractPlatform::TRIM_LEADING;
+        } else if ($this->trailing) {
+            $pos = AbstractPlatform::TRIM_TRAILING;
+        } else if ($this->both) {
+            $pos = AbstractPlatform::TRIM_BOTH;
+        }
+
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getTrimExpression(
+            $sqlWalker->walkStringPrimary($this->stringPrimary),
+            $pos,
+            ($this->trimChar != false) ? $sqlWalker->getConnection()->quote($this->trimChar) : false
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $lexer = $parser->getLexer();
+
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        if (strcasecmp('leading', $lexer->lookahead['value']) === 0) {
+            $parser->match(Lexer::T_LEADING);
+            $this->leading = true;
+        } else if (strcasecmp('trailing', $lexer->lookahead['value']) === 0) {
+            $parser->match(Lexer::T_TRAILING);
+            $this->trailing = true;
+        } else if (strcasecmp('both', $lexer->lookahead['value']) === 0) {
+            $parser->match(Lexer::T_BOTH);
+            $this->both = true;
+        }
+
+        if ($lexer->isNextToken(Lexer::T_STRING)) {
+            $parser->match(Lexer::T_STRING);
+            $this->trimChar = $lexer->token['value'];
+        }
+
+        if ($this->leading || $this->trailing || $this->both || $this->trimChar) {
+            $parser->match(Lexer::T_FROM);
+        }
+
+        $this->stringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/UpperFunction.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/UpperFunction.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Functions/UpperFunction.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST\Functions;
+
+use Doctrine\ORM\Query\Lexer;
+
+/**
+ * "UPPER" "(" StringPrimary ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class UpperFunction extends FunctionNode
+{
+    public $stringPrimary;
+
+    /**
+     * @override
+     */
+    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
+    {
+        return $sqlWalker->getConnection()->getDatabasePlatform()->getUpperExpression(
+               $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary)
+        );
+    }
+
+    /**
+     * @override
+     */
+    public function parse(\Doctrine\ORM\Query\Parser $parser)
+    {
+        $parser->match(Lexer::T_IDENTIFIER);
+        $parser->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $this->stringPrimary = $parser->StringPrimary();
+
+        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GeneralCaseExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GeneralCaseExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GeneralCaseExpression.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+ *
+ * @since   2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GeneralCaseExpression extends Node
+{
+    public $whenClauses = array();
+    public $elseScalarExpression = null;
+
+    public function __construct(array $whenClauses, $elseScalarExpression)
+    {
+        $this->whenClauses = $whenClauses;
+        $this->elseScalarExpression = $elseScalarExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkGeneralCaseExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GroupByClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GroupByClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/GroupByClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Description of GroupByClause
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GroupByClause extends Node
+{
+    public $groupByItems = array();
+
+    public function __construct(array $groupByItems)
+    {
+        $this->groupByItems = $groupByItems;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkGroupByClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/HavingClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/HavingClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/HavingClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Description of HavingClause
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class HavingClause extends Node
+{
+    public $conditionalExpression;
+
+    public function __construct($conditionalExpression)
+    {
+        $this->conditionalExpression = $conditionalExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkHavingClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class IdentificationVariableDeclaration extends Node
+{
+    public $rangeVariableDeclaration = null;
+    public $indexBy = null;
+    public $joinVariableDeclarations = array();
+
+    public function __construct($rangeVariableDecl, $indexBy, array $joinVariableDecls)
+    {
+        $this->rangeVariableDeclaration = $rangeVariableDecl;
+        $this->indexBy = $indexBy;
+        $this->joinVariableDeclarations = $joinVariableDecls;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkIdentificationVariableDeclaration($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InExpression.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * InExpression ::= StateFieldPathExpression ["NOT"] "IN" "(" (Literal {"," Literal}* | Subselect) ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class InExpression extends Node
+{
+    public $not;
+    public $expression;
+    public $literals = array();
+    public $subselect;
+
+    public function __construct($expression)
+    {
+        $this->expression = $expression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkInExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IndexBy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IndexBy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/IndexBy.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class IndexBy extends Node
+{
+    public $simpleStateFieldPathExpression = null;
+
+    public function __construct($simpleStateFieldPathExpression)
+    {
+        $this->simpleStateFieldPathExpression = $simpleStateFieldPathExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkIndexBy($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InputParameter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InputParameter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InputParameter.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Description of InputParameter
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class InputParameter extends Node
+{
+    public $isNamed;
+    public $name;
+
+    /**
+     * @param string $value
+     */
+    public function __construct($value)
+    {
+        if (strlen($value) == 1) {
+            throw \Doctrine\ORM\Query\QueryException::invalidParameterFormat($value);
+        }
+
+        $param = substr($value, 1);
+        $this->isNamed = ! is_numeric($param);
+        $this->name = $param;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkInputParameter($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InstanceOfExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InstanceOfExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/InstanceOfExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")")
+ * InstanceOfParameter  ::= AbstractSchemaName | InputParameter
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class InstanceOfExpression extends Node
+{
+    public $not;
+    public $identificationVariable;
+    public $value;
+
+    public function __construct($identVariable)
+    {
+        $this->identificationVariable = $identVariable;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkInstanceOfExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Join.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Join.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Join.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
+ *          ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Join extends Node
+{
+    const JOIN_TYPE_LEFT = 1;
+    const JOIN_TYPE_LEFTOUTER = 2;
+    const JOIN_TYPE_INNER = 3;
+
+    public $joinType = self::JOIN_TYPE_INNER;
+    public $joinAssociationPathExpression = null;
+    public $aliasIdentificationVariable = null;
+    public $conditionalExpression = null;
+
+    public function __construct($joinType, $joinAssocPathExpr, $aliasIdentVar)
+    {
+        $this->joinType = $joinType;
+        $this->joinAssociationPathExpression = $joinAssocPathExpr;
+        $this->aliasIdentificationVariable = $aliasIdentVar;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkJoin($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * JoinAssociationPathExpression ::= IdentificationVariable "." (SingleValuedAssociationField | CollectionValuedAssociationField)
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class JoinAssociationPathExpression extends Node
+{
+    public $identificationVariable;
+    public $associationField;
+
+    public function __construct($identificationVariable, $associationField)
+    {
+        $this->identificationVariable = $identificationVariable;
+        $this->associationField = $associationField;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkJoinPathExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * JoinVariableDeclaration ::= Join [IndexBy]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class JoinVariableDeclaration extends Node
+{
+    public $join = null;
+    public $indexBy = null;
+
+    public function __construct($join, $indexBy)
+    {
+        $this->join = $join;
+        $this->indexBy = $indexBy;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkJoinVariableDeclaration($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/LikeExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/LikeExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/LikeExpression.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class LikeExpression extends Node
+{
+    public $not;
+    public $stringExpression;
+    public $stringPattern;
+    public $escapeChar;
+
+    public function __construct($stringExpression, $stringPattern, $escapeChar = null)
+    {
+        $this->stringExpression = $stringExpression;
+        $this->stringPattern = $stringPattern;
+        $this->escapeChar = $escapeChar;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkLikeExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Literal.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Literal.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Literal.php	(revision 345)
@@ -0,0 +1,24 @@
+<?php
+
+namespace Doctrine\ORM\Query\AST;
+
+class Literal extends Node
+{
+    const STRING = 1;
+    const BOOLEAN = 2;
+    const NUMERIC = 3;
+
+    public $type;
+    public $value;
+
+    public function __construct($type, $value)
+    {
+        $this->type = $type;
+        $this->value = $value;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkLiteral($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Node.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Node.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Node.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Abstract class of an AST node
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+abstract class Node
+{
+    /**
+     * Double-dispatch method, supposed to dispatch back to the walker.
+     *
+     * Implementation is not mandatory for all nodes.
+     *
+     * @param $walker
+     */
+    public function dispatch($walker)
+    {
+        throw ASTException::noDispatchForNode($this);
+    }
+
+    /**
+     * Dumps the AST Node into a string representation for information purpose only
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->dump($this);
+    }
+
+    public function dump($obj)
+    {
+        static $ident = 0;
+
+        $str = '';
+
+        if ($obj instanceof Node) {
+            $str .= get_class($obj) . '(' . PHP_EOL;
+            $props = get_object_vars($obj);
+
+            foreach ($props as $name => $prop) {
+                $ident += 4;
+                $str .= str_repeat(' ', $ident) . '"' . $name . '": '
+                      . $this->dump($prop) . ',' . PHP_EOL;
+                $ident -= 4;
+            }
+
+            $str .= str_repeat(' ', $ident) . ')';
+        } else if (is_array($obj)) {
+            $ident += 4;
+            $str .= 'array(';
+            $some = false;
+
+            foreach ($obj as $k => $v) {
+                $str .= PHP_EOL . str_repeat(' ', $ident) . '"'
+                      . $k . '" => ' . $this->dump($v) . ',';
+                $some = true;
+            }
+
+            $ident -= 4;
+            $str .= ($some ? PHP_EOL . str_repeat(' ', $ident) : '') . ')';
+        } else if (is_object($obj)) {
+            $str .= 'instanceof(' . get_class($obj) . ')';
+        } else {
+            $str .= var_export($obj, true);
+        }
+
+        return $str;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullComparisonExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullComparisonExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullComparisonExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class NullComparisonExpression extends Node
+{
+    public $not;
+    public $expression;
+
+    public function __construct($expression)
+    {
+        $this->expression = $expression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkNullComparisonExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullIfExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullIfExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/NullIfExpression.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
+ *
+ * @since   2.1
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class NullIfExpression extends Node
+{
+    public $firstExpression;
+
+    public $secondExpression;
+
+    public function __construct($firstExpression, $secondExpression)
+    {
+        $this->firstExpression  = $firstExpression;
+        $this->secondExpression = $secondExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkNullIfExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class OrderByClause extends Node
+{
+    public $orderByItems = array();
+
+    public function __construct(array $orderByItems)
+    {
+        $this->orderByItems = $orderByItems;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkOrderByClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByItem.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByItem.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/OrderByItem.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class OrderByItem extends Node
+{
+    public $expression;
+    public $type;
+
+    public function __construct($expression)
+    {
+        $this->expression = $expression;
+    }
+
+    public function isAsc()
+    {
+        return strtoupper($this->type) == 'ASC';
+    }
+
+    public function isDesc()
+    {
+        return strtoupper($this->type) == 'DESC';
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkOrderByItem($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PartialObjectExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PartialObjectExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PartialObjectExpression.php	(revision 345)
@@ -0,0 +1,15 @@
+<?php
+
+namespace Doctrine\ORM\Query\AST;
+
+class PartialObjectExpression extends Node
+{
+    public $identificationVariable;
+    public $partialFieldSet;
+
+    public function __construct($identificationVariable, array $partialFieldSet)
+    {
+        $this->identificationVariable = $identificationVariable;
+        $this->partialFieldSet = $partialFieldSet;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PathExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PathExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/PathExpression.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
+ * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
+ * StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
+ * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
+ * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
+ * StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
+ * SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class PathExpression extends Node
+{
+    const TYPE_COLLECTION_VALUED_ASSOCIATION = 2;
+    const TYPE_SINGLE_VALUED_ASSOCIATION = 4;
+    const TYPE_STATE_FIELD = 8;
+
+    public $type;
+    public $expectedType;
+    public $identificationVariable;
+    public $field;
+
+    public function __construct($expectedType, $identificationVariable, $field = null)
+    {
+        $this->expectedType = $expectedType;
+        $this->identificationVariable = $identificationVariable;
+        $this->field = $field;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkPathExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/QuantifiedExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/QuantifiedExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/QuantifiedExpression.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class QuantifiedExpression extends Node
+{
+    public $type;
+    public $subselect;
+
+    public function __construct($subselect)
+    {
+        $this->subselect = $subselect;
+    }
+
+    public function isAll()
+    {
+        return strtoupper($this->type) == 'ALL';
+    }
+
+    public function isAny()
+    {
+        return strtoupper($this->type) == 'ANY';
+    }
+
+    public function isSome()
+    {
+        return strtoupper($this->type) == 'SOME';
+    }
+
+    /**
+     * @override
+     */
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkQuantifiedExpression($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class RangeVariableDeclaration extends Node
+{
+    public $abstractSchemaName;
+    public $aliasIdentificationVariable;
+
+    public function __construct($abstractSchemaName, $aliasIdentificationVar)
+    {
+        $this->abstractSchemaName = $abstractSchemaName;
+        $this->aliasIdentificationVariable = $aliasIdentificationVar;
+    }
+
+    public function dispatch($walker)
+    {
+        return $walker->walkRangeVariableDeclaration($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectClause.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SelectClause extends Node
+{
+    public $isDistinct;
+    public $selectExpressions = array();
+
+    public function __construct(array $selectExpressions, $isDistinct)
+    {
+        $this->isDistinct = $isDistinct;
+        $this->selectExpressions = $selectExpressions;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSelectClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectExpression.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
+ *	                    (AggregateExpression | "(" Subselect ")") [["AS"] ["HIDDEN"] FieldAliasIdentificationVariable]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SelectExpression extends Node
+{
+    public $expression;
+    public $fieldIdentificationVariable;
+    public $hiddenAliasResultVariable;
+
+    public function __construct($expression, $fieldIdentificationVariable, $hiddenAliasResultVariable = false)
+    {
+        $this->expression = $expression;
+        $this->fieldIdentificationVariable = $fieldIdentificationVariable;
+        $this->hiddenAliasResultVariable = $hiddenAliasResultVariable;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSelectExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SelectStatement.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SelectStatement extends Node
+{
+    public $selectClause;
+    public $fromClause;
+    public $whereClause;
+    public $groupByClause;
+    public $havingClause;
+    public $orderByClause;
+
+    public function __construct($selectClause, $fromClause) {
+        $this->selectClause = $selectClause;
+        $this->fromClause = $fromClause;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSelectStatement($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SimpleArithmeticExpression extends Node
+{
+    public $arithmeticTerms = array();
+
+    public function __construct(array $arithmeticTerms)
+    {
+        $this->arithmeticTerms = $arithmeticTerms;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSimpleArithmeticExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleCaseExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleCaseExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleCaseExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+ *
+ * @since   2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SimpleCaseExpression extends Node
+{
+    public $caseOperand = null;
+    public $simpleWhenClauses = array();
+    public $elseScalarExpression = null;
+
+    public function __construct($caseOperand, array $simpleWhenClauses, $elseScalarExpression)
+    {
+        $this->caseOperand = $caseOperand;
+        $this->simpleWhenClauses = $simpleWhenClauses;
+        $this->elseScalarExpression = $elseScalarExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSimpleCaseExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectClause.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleSelectClause  ::= "SELECT" ["DISTINCT"] SimpleSelectExpression
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SimpleSelectClause extends Node
+{
+    public $isDistinct = false;
+    public $simpleSelectExpression;
+
+    public function __construct($simpleSelectExpression, $isDistinct)
+    {
+        $this->simpleSelectExpression = $simpleSelectExpression;
+        $this->isDistinct = $isDistinct;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSimpleSelectClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectExpression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectExpression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleSelectExpression.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleSelectExpression ::= StateFieldPathExpression | IdentificationVariable
+ *                          | (AggregateExpression [["AS"] FieldAliasIdentificationVariable])
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SimpleSelectExpression extends Node
+{
+    public $expression;
+    public $fieldIdentificationVariable;
+
+    public function __construct($expression)
+    {
+        $this->expression = $expression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSimpleSelectExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleWhenClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleWhenClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SimpleWhenClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+ *
+ * @since   2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SimpleWhenClause extends Node
+{
+    public $caseScalarExpression = null;
+    public $thenScalarExpression = null;
+
+    public function __construct($caseScalarExpression, $thenScalarExpression)
+    {
+        $this->caseScalarExpression = $caseScalarExpression;
+        $this->thenScalarExpression = $thenScalarExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkWhenClauseExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Subselect.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Subselect.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/Subselect.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Subselect extends Node
+{
+    public $simpleSelectClause;
+    public $subselectFromClause;
+    public $whereClause;
+    public $groupByClause;
+    public $havingClause;
+    public $orderByClause;
+
+    public function __construct($simpleSelectClause, $subselectFromClause)
+    {
+        $this->simpleSelectClause = $simpleSelectClause;
+        $this->subselectFromClause = $subselectFromClause;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSubselect($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SubselectFromClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SubselectFromClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/SubselectFromClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class SubselectFromClause extends Node
+{
+    public $identificationVariableDeclarations = array();
+
+    public function __construct(array $identificationVariableDeclarations)
+    {
+        $this->identificationVariableDeclarations = $identificationVariableDeclarations;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkSubselectFromClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateClause.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] AliasIdentificationVariable] "SET" UpdateItem {"," UpdateItem}*
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class UpdateClause extends Node
+{
+    public $abstractSchemaName;
+    public $aliasIdentificationVariable;
+    public $updateItems = array();
+
+    public function __construct($abstractSchemaName, array $updateItems)
+    {
+        $this->abstractSchemaName = $abstractSchemaName;
+        $this->updateItems = $updateItems;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkUpdateClause($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateItem.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateItem.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateItem.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * UpdateItem ::= [IdentificationVariable "."] {StateField | SingleValuedAssociationField} "=" NewValue
+ * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
+ *              EnumPrimary | SimpleEntityExpression | "NULL"
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class UpdateItem extends Node
+{
+    public $pathExpression;
+    public $newValue;
+
+    public function __construct($pathExpression, $newValue)
+    {
+        $this->pathExpression = $pathExpression;
+        $this->newValue = $newValue;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkUpdateItem($this);
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateStatement.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateStatement.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/UpdateStatement.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * UpdateStatement = UpdateClause [WhereClause]
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class UpdateStatement extends Node
+{
+    public $updateClause;
+    public $whereClause;
+
+    public function __construct($updateClause)
+    {
+        $this->updateClause = $updateClause;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkUpdateStatement($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhenClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhenClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhenClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+ *
+ * @since   2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class WhenClause extends Node
+{
+    public $caseConditionExpression = null;
+    public $thenScalarExpression = null;
+
+    public function __construct($caseConditionExpression, $thenScalarExpression)
+    {
+        $this->caseConditionExpression = $caseConditionExpression;
+        $this->thenScalarExpression = $thenScalarExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkWhenClauseExpression($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhereClause.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhereClause.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/AST/WhereClause.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * WhereClause ::= "WHERE" ConditionalExpression
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class WhereClause extends Node
+{
+    public $conditionalExpression;
+
+    public function __construct($conditionalExpression)
+    {
+        $this->conditionalExpression = $conditionalExpression;
+    }
+
+    public function dispatch($sqlWalker)
+    {
+        return $sqlWalker->walkWhereClause($this);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Exec;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Cache\QueryCacheProfile;
+
+/**
+ * Base class for SQL statement executors.
+ *
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        http://www.doctrine-project.org
+ * @since       2.0
+ * @todo Rename: AbstractSQLExecutor
+ */
+abstract class AbstractSqlExecutor
+{
+    /**
+     * @var array
+     */
+    protected $_sqlStatements;
+
+    /**
+     * @var QueryCacheProfile
+     */
+    protected $queryCacheProfile;
+
+    /**
+     * Gets the SQL statements that are executed by the executor.
+     *
+     * @return array  All the SQL update statements.
+     */
+    public function getSqlStatements()
+    {
+        return $this->_sqlStatements;
+    }
+
+    public function setQueryCacheProfile(QueryCacheProfile $qcp)
+    {
+        $this->queryCacheProfile = $qcp;
+    }
+
+    /**
+     * Executes all sql statements.
+     *
+     * @param \Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries.
+     * @param array $params  The parameters.
+     * @param array $types The parameter types.
+     * @return \Doctrine\DBAL\Driver\Statement
+     */
+    abstract public function execute(Connection $conn, array $params, array $types);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php	(revision 345)
@@ -0,0 +1,124 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Exec;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\ORM\Query\AST;
+
+/**
+ * Executes the SQL statements for bulk DQL DELETE statements on classes in
+ * Class Table Inheritance (JOINED).
+ *
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        http://www.doctrine-project.org
+ * @since       2.0
+ */
+class MultiTableDeleteExecutor extends AbstractSqlExecutor
+{
+    private $_createTempTableSql;
+    private $_dropTempTableSql;
+    private $_insertSql;
+
+    /**
+     * Initializes a new <tt>MultiTableDeleteExecutor</tt>.
+     *
+     * @param Node $AST The root AST node of the DQL query.
+     * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST.
+     * @internal Any SQL construction and preparation takes place in the constructor for
+     *           best performance. With a query cache the executor will be cached.
+     */
+    public function __construct(AST\Node $AST, $sqlWalker)
+    {
+        $em = $sqlWalker->getEntityManager();
+        $conn = $em->getConnection();
+        $platform = $conn->getDatabasePlatform();
+
+        $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
+        $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
+        $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
+
+        $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
+        $idColumnNames = $rootClass->getIdentifierColumnNames();
+        $idColumnList = implode(', ', $idColumnNames);
+
+        // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
+        $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias);
+
+        $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')'
+                . ' SELECT t0.' . implode(', t0.', $idColumnNames);
+
+        $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias);
+        $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array())));
+        $this->_insertSql .= $sqlWalker->walkFromClause($fromClause);
+
+        // Append WHERE clause, if there is one.
+        if ($AST->whereClause) {
+            $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause);
+        }
+
+        // 2. Create ID subselect statement used in DELETE ... WHERE ... IN (subselect)
+        $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable;
+
+        // 3. Create and store DELETE statements
+        $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses);
+        foreach (array_reverse($classNames) as $className) {
+            $tableName = $em->getClassMetadata($className)->getQuotedTableName($platform);
+            $this->_sqlStatements[] = 'DELETE FROM ' . $tableName
+                    . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
+        }
+
+        // 4. Store DDL for temporary identifier table.
+        $columnDefinitions = array();
+        foreach ($idColumnNames as $idColumnName) {
+            $columnDefinitions[$idColumnName] = array(
+                'notnull' => true,
+                'type' => \Doctrine\DBAL\Types\Type::getType($rootClass->getTypeOfColumn($idColumnName))
+            );
+        }
+        $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
+                . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
+        $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function execute(Connection $conn, array $params, array $types)
+    {
+        $numDeleted = 0;
+
+        // Create temporary id table
+        $conn->executeUpdate($this->_createTempTableSql);
+
+        // Insert identifiers
+        $numDeleted = $conn->executeUpdate($this->_insertSql, $params, $types);
+
+        // Execute DELETE statements
+        foreach ($this->_sqlStatements as $sql) {
+            $conn->executeUpdate($sql);
+        }
+
+        // Drop temporary table
+        $conn->executeUpdate($this->_dropTempTableSql);
+
+        return $numDeleted;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php	(revision 345)
@@ -0,0 +1,178 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Exec;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\Query\AST;
+
+/**
+ * Executes the SQL statements for bulk DQL UPDATE statements on classes in
+ * Class Table Inheritance (JOINED).
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class MultiTableUpdateExecutor extends AbstractSqlExecutor
+{
+    private $_createTempTableSql;
+    private $_dropTempTableSql;
+    private $_insertSql;
+    private $_sqlParameters = array();
+    private $_numParametersInUpdateClause = 0;
+
+    /**
+     * Initializes a new <tt>MultiTableUpdateExecutor</tt>.
+     *
+     * @param Node $AST The root AST node of the DQL query.
+     * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST.
+     * @internal Any SQL construction and preparation takes place in the constructor for
+     *           best performance. With a query cache the executor will be cached.
+     */
+    public function __construct(AST\Node $AST, $sqlWalker)
+    {
+        $em = $sqlWalker->getEntityManager();
+        $conn = $em->getConnection();
+        $platform = $conn->getDatabasePlatform();
+
+        $updateClause = $AST->updateClause;
+
+        $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
+        $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
+
+        $updateItems = $updateClause->updateItems;
+
+        $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
+        $idColumnNames = $rootClass->getIdentifierColumnNames();
+        $idColumnList = implode(', ', $idColumnNames);
+
+        // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
+        $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable);
+
+        $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')'
+                . ' SELECT t0.' . implode(', t0.', $idColumnNames);
+
+        $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable);
+        $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array())));
+
+        $this->_insertSql .= $sqlWalker->walkFromClause($fromClause);
+
+        // 2. Create ID subselect statement used in UPDATE ... WHERE ... IN (subselect)
+        $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable;
+
+        // 3. Create and store UPDATE statements
+        $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses);
+        $i = -1;
+
+        foreach (array_reverse($classNames) as $className) {
+            $affected = false;
+            $class = $em->getClassMetadata($className);
+            $updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET ';
+
+            foreach ($updateItems as $updateItem) {
+                $field = $updateItem->pathExpression->field;
+
+                if (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]['inherited']) ||
+                    isset($class->associationMappings[$field]) && ! isset($class->associationMappings[$field]['inherited'])) {
+                    $newValue = $updateItem->newValue;
+
+                    if ( ! $affected) {
+                        $affected = true;
+                        ++$i;
+                    } else {
+                        $updateSql .= ', ';
+                    }
+
+                    $updateSql .= $sqlWalker->walkUpdateItem($updateItem);
+
+                    //FIXME: parameters can be more deeply nested. traverse the tree.
+                    //FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
+                    if ($newValue instanceof AST\InputParameter) {
+                        $paramKey = $newValue->name;
+                        $this->_sqlParameters[$i]['parameters'][] = $sqlWalker->getQuery()->getParameter($paramKey);
+                        $this->_sqlParameters[$i]['types'][] = $sqlWalker->getQuery()->getParameterType($paramKey);
+
+                        ++$this->_numParametersInUpdateClause;
+                    }
+                }
+            }
+
+            if ($affected) {
+                $this->_sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
+            }
+        }
+
+        // Append WHERE clause to insertSql, if there is one.
+        if ($AST->whereClause) {
+            $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause);
+        }
+
+        // 4. Store DDL for temporary identifier table.
+        $columnDefinitions = array();
+
+        foreach ($idColumnNames as $idColumnName) {
+            $columnDefinitions[$idColumnName] = array(
+                'notnull' => true,
+                'type' => Type::getType($rootClass->getTypeOfColumn($idColumnName))
+            );
+        }
+
+        $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
+                . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
+
+        $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function execute(Connection $conn, array $params, array $types)
+    {
+        $numUpdated = 0;
+
+        // Create temporary id table
+        $conn->executeUpdate($this->_createTempTableSql);
+
+        // Insert identifiers. Parameters from the update clause are cut off.
+        $numUpdated = $conn->executeUpdate(
+            $this->_insertSql,
+            array_slice($params, $this->_numParametersInUpdateClause),
+            array_slice($types, $this->_numParametersInUpdateClause)
+        );
+
+        // Execute UPDATE statements
+        for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) {
+            $parameters = array();
+            $types      = array();
+
+            if (isset($this->_sqlParameters[$i])) {
+                $parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array();
+                $types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array();
+            }
+
+            $conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types);
+        }
+
+        // Drop temporary table
+        $conn->executeUpdate($this->_dropTempTableSql);
+
+        return $numUpdated;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Exec;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\ORM\Query\AST\SelectStatement,
+    Doctrine\ORM\Query\SqlWalker;
+
+/**
+ * Executor that executes the SQL statement for simple DQL SELECT statements.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ */
+class SingleSelectExecutor extends AbstractSqlExecutor
+{
+    public function __construct(SelectStatement $AST, SqlWalker $sqlWalker)
+    {
+        $this->_sqlStatements = $sqlWalker->walkSelectStatement($AST);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function execute(Connection $conn, array $params, array $types)
+    {
+        return $conn->executeQuery($this->_sqlStatements, $params, $types, $this->queryCacheProfile);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Exec;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\ORM\Query\AST;
+
+/**
+ * Executor that executes the SQL statements for DQL DELETE/UPDATE statements on classes
+ * that are mapped to a single table.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @todo This is exactly the same as SingleSelectExecutor. Unify in SingleStatementExecutor.
+ */
+class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor
+{
+    public function __construct(AST\Node $AST, $sqlWalker)
+    {
+        if ($AST instanceof AST\UpdateStatement) {
+            $this->_sqlStatements = $sqlWalker->walkUpdateStatement($AST);
+        } else if ($AST instanceof AST\DeleteStatement) {
+            $this->_sqlStatements = $sqlWalker->walkDeleteStatement($AST);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function execute(Connection $conn, array $params, array $types)
+    {
+        return $conn->executeUpdate($this->_sqlStatements, $params, $types);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr.php	(revision 345)
@@ -0,0 +1,595 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * This class is used to generate DQL expressions via a set of PHP static functions
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Rename: ExpressionBuilder
+ */
+class Expr
+{
+    /**
+     * Creates a conjunction of the given boolean expressions.
+     *
+     * Example:
+     *
+     *     [php]
+     *     // (u.type = ?1) AND (u.role = ?2)
+     *     $expr->andX($expr->eq('u.type', ':1'), $expr->eq('u.role', ':2'));
+     *
+     * @param \Doctrine\ORM\Query\Expr\Comparison |
+     *          \Doctrine\ORM\Query\Expr\Func |
+     *          \Doctrine\ORM\Query\Expr\Orx
+    *               $x Optional clause. Defaults = null, but requires at least one defined when converting to string.
+     * @return Expr\Andx
+     */
+    public function andX($x = null)
+    {
+        return new Expr\Andx(func_get_args());
+    }
+
+    /**
+     * Creates a disjunction of the given boolean expressions.
+     *
+     * Example:
+     *
+     *     [php]
+     *     // (u.type = ?1) OR (u.role = ?2)
+     *     $q->where($q->expr()->orX('u.type = ?1', 'u.role = ?2'));
+     *
+     * @param mixed $x Optional clause. Defaults = null, but requires
+     *                 at least one defined when converting to string.
+     * @return Expr\Orx
+     */
+    public function orX($x = null)
+    {
+        return new Expr\Orx(func_get_args());
+    }
+
+    /**
+     * Creates an ASCending order expression.
+     *
+     * @param $sort
+     * @return Expr\OrderBy
+     */
+    public function asc($expr)
+    {
+        return new Expr\OrderBy($expr, 'ASC');
+    }
+
+    /**
+     * Creates a DESCending order expression.
+     *
+     * @param $sort
+     * @return Expr\OrderBy
+     */
+    public function desc($expr)
+    {
+        return new Expr\OrderBy($expr, 'DESC');
+    }
+
+    /**
+     * Creates an equality comparison expression with the given arguments.
+     *
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> = <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id = ?1
+     *     $expr->eq('u.id', '?1');
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function eq($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::EQ, $y);
+    }
+
+    /**
+     * Creates an instance of Expr\Comparison, with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> <> <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id <> ?1
+     *     $q->where($q->expr()->neq('u.id', '?1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function neq($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::NEQ, $y);
+    }
+
+    /**
+     * Creates an instance of Expr\Comparison, with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> < <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id < ?1
+     *     $q->where($q->expr()->lt('u.id', '?1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function lt($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::LT, $y);
+    }
+
+    /**
+     * Creates an instance of Expr\Comparison, with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> <= <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id <= ?1
+     *     $q->where($q->expr()->lte('u.id', '?1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function lte($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::LTE, $y);
+    }
+
+    /**
+     * Creates an instance of Expr\Comparison, with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> > <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id > ?1
+     *     $q->where($q->expr()->gt('u.id', '?1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function gt($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::GT, $y);
+    }
+
+    /**
+     * Creates an instance of Expr\Comparison, with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> >= <right expr>. Example:
+     *
+     *     [php]
+     *     // u.id >= ?1
+     *     $q->where($q->expr()->gte('u.id', '?1'));
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Comparison
+     */
+    public function gte($x, $y)
+    {
+        return new Expr\Comparison($x, Expr\Comparison::GTE, $y);
+    }
+
+    /**
+     * Creates an instance of AVG() function, with the given argument.
+     *
+     * @param mixed $x Argument to be used in AVG() function.
+     * @return Expr\Func
+     */
+    public function avg($x)
+    {
+        return new Expr\Func('AVG', array($x));
+    }
+
+    /**
+     * Creates an instance of MAX() function, with the given argument.
+     *
+     * @param mixed $x Argument to be used in MAX() function.
+     * @return Expr\Func
+     */
+    public function max($x)
+    {
+        return new Expr\Func('MAX', array($x));
+    }
+
+    /**
+     * Creates an instance of MIN() function, with the given argument.
+     *
+     * @param mixed $x Argument to be used in MIN() function.
+     * @return Expr\Func
+     */
+    public function min($x)
+    {
+        return new Expr\Func('MIN', array($x));
+    }
+
+    /**
+     * Creates an instance of COUNT() function, with the given argument.
+     *
+     * @param mixed $x Argument to be used in COUNT() function.
+     * @return Expr\Func
+     */
+    public function count($x)
+    {
+        return new Expr\Func('COUNT', array($x));
+    }
+
+    /**
+     * Creates an instance of COUNT(DISTINCT) function, with the given argument.
+     *
+     * @param mixed $x Argument to be used in COUNT(DISTINCT) function.
+     * @return string
+     */
+    public function countDistinct($x)
+    {
+        return 'COUNT(DISTINCT ' . implode(', ', func_get_args()) . ')';
+    }
+
+    /**
+     * Creates an instance of EXISTS() function, with the given DQL Subquery.
+     *
+     * @param mixed $subquery DQL Subquery to be used in EXISTS() function.
+     * @return Expr\Func
+     */
+    public function exists($subquery)
+    {
+        return new Expr\Func('EXISTS', array($subquery));
+    }
+
+    /**
+     * Creates an instance of ALL() function, with the given DQL Subquery.
+     *
+     * @param mixed $subquery DQL Subquery to be used in ALL() function.
+     * @return Expr\Func
+     */
+    public function all($subquery)
+    {
+        return new Expr\Func('ALL', array($subquery));
+    }
+
+    /**
+     * Creates a SOME() function expression with the given DQL subquery.
+     *
+     * @param mixed $subquery DQL Subquery to be used in SOME() function.
+     * @return Expr\Func
+     */
+    public function some($subquery)
+    {
+        return new Expr\Func('SOME', array($subquery));
+    }
+
+    /**
+     * Creates an ANY() function expression with the given DQL subquery.
+     *
+     * @param mixed $subquery DQL Subquery to be used in ANY() function.
+     * @return Expr\Func
+     */
+    public function any($subquery)
+    {
+        return new Expr\Func('ANY', array($subquery));
+    }
+
+    /**
+     * Creates a negation expression of the given restriction.
+     *
+     * @param mixed $restriction Restriction to be used in NOT() function.
+     * @return Expr\Func
+     */
+    public function not($restriction)
+    {
+        return new Expr\Func('NOT', array($restriction));
+    }
+
+    /**
+     * Creates an ABS() function expression with the given argument.
+     *
+     * @param mixed $x Argument to be used in ABS() function.
+     * @return Expr\Func
+     */
+    public function abs($x)
+    {
+        return new Expr\Func('ABS', array($x));
+    }
+
+    /**
+     * Creates a product mathematical expression with the given arguments.
+     *
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> * <right expr>. Example:
+     *
+     *     [php]
+     *     // u.salary * u.percentAnualSalaryIncrease
+     *     $q->expr()->prod('u.salary', 'u.percentAnualSalaryIncrease')
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Math
+     */
+    public function prod($x, $y)
+    {
+        return new Expr\Math($x, '*', $y);
+    }
+
+    /**
+     * Creates a difference mathematical expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> - <right expr>. Example:
+     *
+     *     [php]
+     *     // u.monthlySubscriptionCount - 1
+     *     $q->expr()->diff('u.monthlySubscriptionCount', '1')
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Math
+     */
+    public function diff($x, $y)
+    {
+        return new Expr\Math($x, '-', $y);
+    }
+
+    /**
+     * Creates a sum mathematical expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> + <right expr>. Example:
+     *
+     *     [php]
+     *     // u.numChildren + 1
+     *     $q->expr()->diff('u.numChildren', '1')
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Math
+     */
+    public function sum($x, $y)
+    {
+        return new Expr\Math($x, '+', $y);
+    }
+
+    /**
+     * Creates a quotient mathematical expression with the given arguments.
+     * First argument is considered the left expression and the second is the right expression.
+     * When converted to string, it will generated a <left expr> / <right expr>. Example:
+     *
+     *     [php]
+     *     // u.total / u.period
+     *     $expr->quot('u.total', 'u.period')
+     *
+     * @param mixed $x Left expression
+     * @param mixed $y Right expression
+     * @return Expr\Math
+     */
+    public function quot($x, $y)
+    {
+        return new Expr\Math($x, '/', $y);
+    }
+
+    /**
+     * Creates a SQRT() function expression with the given argument.
+     *
+     * @param mixed $x Argument to be used in SQRT() function.
+     * @return Expr\Func
+     */
+    public function sqrt($x)
+    {
+        return new Expr\Func('SQRT', array($x));
+    }
+
+    /**
+     * Creates an IN() expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by IN() function
+     * @param mixed $y Argument to be used in IN() function.
+     * @return Expr\Func
+     */
+    public function in($x, $y)
+    {
+        if (is_array($y)) {
+            foreach ($y as &$literal) {
+                if ( ! ($literal instanceof Expr\Literal)) {
+                    $literal = $this->_quoteLiteral($literal);
+                }
+            }
+        }
+        return new Expr\Func($x . ' IN', (array) $y);
+    }
+
+    /**
+     * Creates a NOT IN() expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by NOT IN() function
+     * @param mixed $y Argument to be used in NOT IN() function.
+     * @return Expr\Func
+     */
+    public function notIn($x, $y)
+    {
+        if (is_array($y)) {
+            foreach ($y as &$literal) {
+                if ( ! ($literal instanceof Expr\Literal)) {
+                    $literal = $this->_quoteLiteral($literal);
+                }
+            }
+        }
+        return new Expr\Func($x . ' NOT IN', (array) $y);
+    }
+
+    /**
+     * Creates an IS NULL expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by IS NULL
+     * @return string
+     */
+    public function isNull($x)
+    {
+        return $x . ' IS NULL';
+    }
+
+    /**
+     * Creates an IS NOT NULL expression with the given arguments.
+     *
+     * @param string $x Field in string format to be restricted by IS NOT NULL
+     * @return string
+     */
+    public function isNotNull($x)
+    {
+        return $x . ' IS NOT NULL';
+    }
+
+    /**
+     * Creates a LIKE() comparison expression with the given arguments.
+     *
+     * @param string $x Field in string format to be inspected by LIKE() comparison.
+     * @param mixed $y Argument to be used in LIKE() comparison.
+     * @return Expr\Comparison
+     */
+    public function like($x, $y)
+    {
+        return new Expr\Comparison($x, 'LIKE', $y);
+    }
+
+    /**
+     * Creates a CONCAT() function expression with the given arguments.
+     *
+     * @param mixed $x First argument to be used in CONCAT() function.
+     * @param mixed $x Second argument to be used in CONCAT() function.
+     * @return Expr\Func
+     */
+    public function concat($x, $y)
+    {
+        return new Expr\Func('CONCAT', array($x, $y));
+    }
+
+    /**
+     * Creates a SUBSTRING() function expression with the given arguments.
+     *
+     * @param mixed $x Argument to be used as string to be cropped by SUBSTRING() function.
+     * @param integer $from Initial offset to start cropping string. May accept negative values.
+     * @param integer $len Length of crop. May accept negative values.
+     * @return Expr\Func
+     */
+    public function substring($x, $from, $len = null)
+    {
+        $args = array($x, $from);
+        if (null !== $len) {
+            $args[] = $len;
+        }
+        return new Expr\Func('SUBSTRING', $args);
+    }
+
+    /**
+     * Creates a LOWER() function expression with the given argument.
+     *
+     * @param mixed $x Argument to be used in LOWER() function.
+     * @return Expr\Func A LOWER function expression.
+     */
+    public function lower($x)
+    {
+        return new Expr\Func('LOWER', array($x));
+    }
+
+    /**
+     * Creates an UPPER() function expression with the given argument.
+     *
+     * @param mixed $x Argument to be used in UPPER() function.
+     * @return Expr\Func An UPPER function expression.
+     */
+    public function upper($x)
+    {
+        return new Expr\Func('UPPER', array($x));
+    }
+
+    /**
+     * Creates a LENGTH() function expression with the given argument.
+     *
+     * @param mixed $x Argument to be used as argument of LENGTH() function.
+     * @return Expr\Func A LENGTH function expression.
+     */
+    public function length($x)
+    {
+        return new Expr\Func('LENGTH', array($x));
+    }
+
+    /**
+     * Creates a literal expression of the given argument.
+     *
+     * @param mixed $literal Argument to be converted to literal.
+     * @return Expr\Literal
+     */
+    public function literal($literal)
+    {
+        return new Expr\Literal($this->_quoteLiteral($literal));
+    }
+
+    /**
+     * Quotes a literal value, if necessary, according to the DQL syntax.
+     *
+     * @param mixed $literal The literal value.
+     * @return string
+     */
+    private function _quoteLiteral($literal)
+    {
+        if (is_numeric($literal) && !is_string($literal)) {
+            return (string) $literal;
+        } else if (is_bool($literal)) {
+            return $literal ? "true" : "false";
+        } else {
+            return "'" . str_replace("'", "''", $literal) . "'";
+        }
+    }
+
+    /**
+     * Creates an instance of BETWEEN() function, with the given argument.
+     *
+     * @param mixed $val Valued to be inspected by range values.
+     * @param integer $x Starting range value to be used in BETWEEN() function.
+     * @param integer $y End point value to be used in BETWEEN() function.
+     * @return Expr\Func A BETWEEN expression.
+     */
+    public function between($val, $x, $y)
+    {
+        return $val . ' BETWEEN ' . $x . ' AND ' . $y;
+    }
+
+    /**
+     * Creates an instance of TRIM() function, with the given argument.
+     *
+     * @param mixed $x Argument to be used as argument of TRIM() function.
+     * @return Expr\Func a TRIM expression.
+     */
+    public function trim($x)
+    {
+        return new Expr\Func('TRIM', $x);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Andx.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Andx.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Andx.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL and parts
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Andx extends Composite
+{
+    protected $_separator = ' AND ';
+    protected $_allowedClasses = array(
+        'Doctrine\ORM\Query\Expr\Comparison',
+        'Doctrine\ORM\Query\Expr\Func',
+        'Doctrine\ORM\Query\Expr\Orx',
+        'Doctrine\ORM\Query\Expr\Andx',
+    );
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Base.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Base.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Base.php	(revision 345)
@@ -0,0 +1,89 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Abstract base Expr class for building DQL parts
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+abstract class Base
+{
+    protected $_preSeparator = '(';
+    protected $_separator = ', ';
+    protected $_postSeparator = ')';
+    protected $_allowedClasses = array();
+
+    protected $_parts = array();
+
+    public function __construct($args = array())
+    {
+        $this->addMultiple($args);
+    }
+
+    public function addMultiple($args = array())
+    {
+        foreach ((array) $args as $arg) {
+            $this->add($arg);
+        }
+
+        return $this;
+    }
+
+    public function add($arg)
+    {
+        if ( $arg !== null || ($arg instanceof self && $arg->count() > 0) ) {
+            // If we decide to keep Expr\Base instances, we can use this check
+            if ( ! is_string($arg)) {
+                $class = get_class($arg);
+
+                if ( ! in_array($class, $this->_allowedClasses)) {
+                    throw new \InvalidArgumentException("Expression of type '$class' not allowed in this context.");
+                }
+            }
+
+            $this->_parts[] = $arg;
+        }
+
+        return $this;
+    }
+
+    public function count()
+    {
+        return count($this->_parts);
+    }
+
+    public function __toString()
+    {
+        if ($this->count() == 1) {
+            return (string) $this->_parts[0];
+        }
+
+        return $this->_preSeparator . implode($this->_separator, $this->_parts) . $this->_postSeparator;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Comparison.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Comparison.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Comparison.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for DQL comparison expressions
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Comparison
+{
+    const EQ  = '=';
+    const NEQ = '<>';
+    const LT  = '<';
+    const LTE = '<=';
+    const GT  = '>';
+    const GTE = '>=';
+
+    private $_leftExpr;
+    private $_operator;
+    private $_rightExpr;
+
+    public function __construct($leftExpr, $operator, $rightExpr)
+    {
+        $this->_leftExpr  = $leftExpr;
+        $this->_operator  = $operator;
+        $this->_rightExpr = $rightExpr;
+    }
+
+    public function __toString()
+    {
+        return $this->_leftExpr . ' ' . $this->_operator . ' ' . $this->_rightExpr;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Composite.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Composite.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Composite.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL and parts
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Composite extends Base
+{
+    public function __toString()
+    {
+        if ($this->count() === 1) {
+            return (string) $this->_parts[0];
+        }
+
+        $components = array();
+
+        foreach ($this->_parts as $part) {
+            $components[] = $this->processQueryPart($part);
+        }
+
+        return implode($this->_separator, $components);
+    }
+
+
+    private function processQueryPart($part)
+    {
+        $queryPart = (string) $part;
+
+        if (is_object($part) && $part instanceof self && $part->count() > 1) {
+            return $this->_preSeparator . $queryPart . $this->_postSeparator;
+        }
+
+        // Fixes DDC-1237: User may have added a where item containing nested expression (with "OR" or "AND")
+        if (stripos($queryPart, ' OR ') !== false || stripos($queryPart, ' AND ') !== false) {
+            return $this->_preSeparator . $queryPart . $this->_postSeparator;
+        }
+
+        return $queryPart;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/From.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/From.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/From.php	(revision 345)
@@ -0,0 +1,88 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for DQL from
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class From
+{
+    /**
+     * @var string
+     */
+    private $_from;
+
+    /**
+     * @var string
+     */
+    private $_alias;
+
+    /**
+     * @var string
+     */
+    private $_indexBy;
+
+    /**
+     * @param string $from      The class name.
+     * @param string $alias     The alias of the class.
+     * @param string $indexBy   The index for the from.
+     */
+    public function __construct($from, $alias, $indexBy = null)
+    {
+        $this->_from    = $from;
+        $this->_alias   = $alias;
+        $this->_indexBy = $indexBy;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFrom()
+    {
+        return $this->_from;
+    }
+
+    /**
+     * @return string
+     */
+    public function getAlias()
+    {
+        return $this->_alias;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->_from . ' ' . $this->_alias .
+                ($this->_indexBy ? ' INDEX BY ' . $this->_indexBy : '');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Func.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Func.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Func.php	(revision 345)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for generating DQL functions
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Func
+{
+    private $_name;
+    private $_arguments;
+
+    public function __construct($name, $arguments)
+    {
+        $this->_name = $name;
+        $this->_arguments = (array) $arguments;
+    }
+
+    public function __toString()
+    {
+        return $this->_name . '(' . implode(', ', $this->_arguments) . ')';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/GroupBy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/GroupBy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/GroupBy.php	(revision 345)
@@ -0,0 +1,39 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL Group By parts
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GroupBy extends Base
+{
+    protected $_preSeparator = '';
+    protected $_postSeparator = '';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Join.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Join.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Join.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for DQL from
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Join
+{
+    const INNER_JOIN = 'INNER';
+    const LEFT_JOIN  = 'LEFT';
+
+    const ON   = 'ON';
+    const WITH = 'WITH';
+
+    private $_joinType;
+    private $_join;
+    private $_alias;
+    private $_conditionType;
+    private $_condition;
+    private $_indexBy;
+
+    public function __construct($joinType, $join, $alias = null, $conditionType = null, $condition = null, $indexBy = null)
+    {
+        $this->_joinType       = $joinType;
+        $this->_join           = $join;
+        $this->_alias          = $alias;
+        $this->_conditionType  = $conditionType;
+        $this->_condition      = $condition;
+        $this->_indexBy        = $indexBy;
+    }
+
+    public function __toString()
+    {
+        return strtoupper($this->_joinType) . ' JOIN ' . $this->_join
+             . ($this->_alias ? ' ' . $this->_alias : '')
+             . ($this->_condition ? ' ' . strtoupper($this->_conditionType) . ' ' . $this->_condition : '')
+             . ($this->_indexBy ? ' INDEX BY ' . $this->_indexBy : '');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Literal.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Literal.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Literal.php	(revision 345)
@@ -0,0 +1,9 @@
+<?php
+
+namespace Doctrine\ORM\Query\Expr;
+
+class Literal extends Base
+{
+    protected $_preSeparator = '';
+    protected $_postSeparator = '';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Math.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Math.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Math.php	(revision 345)
@@ -0,0 +1,66 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for DQL math statements
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Math
+{
+    private $_leftExpr;
+    private $_operator;
+    private $_rightExpr;
+
+    public function __construct($leftExpr, $operator, $rightExpr)
+    {
+        $this->_leftExpr  = $leftExpr;
+        $this->_operator  = $operator;
+        $this->_rightExpr = $rightExpr;
+    }
+
+    public function __toString()
+    {
+        // Adjusting Left Expression
+        $leftExpr = (string) $this->_leftExpr;
+
+        if ($this->_leftExpr instanceof Math) {
+            $leftExpr = '(' . $leftExpr . ')';
+        }
+
+        // Adjusting Right Expression
+        $rightExpr = (string) $this->_rightExpr;
+
+        if ($this->_rightExpr instanceof Math) {
+            $rightExpr = '(' . $rightExpr . ')';
+        }
+
+        return $leftExpr . ' ' . $this->_operator . ' ' . $rightExpr;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/OrderBy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/OrderBy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/OrderBy.php	(revision 345)
@@ -0,0 +1,66 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL Order By parts
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class OrderBy
+{
+    protected $_preSeparator = '';
+    protected $_separator = ', ';
+    protected $_postSeparator = '';
+    protected $_allowedClasses = array();
+
+    private $_parts = array();
+
+    public function __construct($sort = null, $order = null)
+    {
+        if ($sort) {
+            $this->add($sort, $order);
+        }
+    }
+
+    public function add($sort, $order = null)
+    {
+        $order = ! $order ? 'ASC' : $order;
+        $this->_parts[] = $sort . ' '. $order;
+    }
+
+    public function count()
+    {
+        return count($this->_parts);
+    }
+
+    public function __tostring()
+    {
+        return $this->_preSeparator . implode($this->_separator, $this->_parts) . $this->_postSeparator;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Orx.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Orx.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Orx.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL OR clauses
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Orx extends Composite
+{
+    protected $_separator = ' OR ';
+    protected $_allowedClasses = array(
+        'Doctrine\ORM\Query\Expr\Comparison',
+        'Doctrine\ORM\Query\Expr\Func',
+        'Doctrine\ORM\Query\Expr\Andx',
+        'Doctrine\ORM\Query\Expr\Orx',
+    );
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Select.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Select.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Expr/Select.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Expr;
+
+/**
+ * Expression class for building DQL select statements
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Select extends Base
+{
+    protected $_preSeparator = '';
+    protected $_postSeparator = '';
+    protected $_allowedClasses = array(
+        'Doctrine\ORM\Query\Expr\Func'
+    );
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Filter/SQLFilter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Filter/SQLFilter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Filter/SQLFilter.php	(revision 345)
@@ -0,0 +1,122 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\Filter;
+
+use Doctrine\ORM\EntityManager,
+    Doctrine\ORM\Mapping\ClassMetaData,
+    Doctrine\ORM\Query\ParameterTypeInferer;
+
+/**
+ * The base class that user defined filters should extend.
+ *
+ * Handles the setting and escaping of parameters.
+ *
+ * @author Alexander <iam.asm89@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @abstract
+ */
+abstract class SQLFilter
+{
+    /**
+     * The entity manager.
+     * @var EntityManager
+     */
+    private $em;
+
+    /**
+     * Parameters for the filter.
+     * @var array
+     */
+    private $parameters;
+
+    /**
+     * Constructs the SQLFilter object.
+     *
+     * @param EntityManager $em The EM
+     */
+    final public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Sets a parameter that can be used by the filter.
+     *
+     * @param string $name Name of the parameter.
+     * @param string $value Value of the parameter.
+     * @param string $type The parameter type. If specified, the given value will be run through
+     *                     the type conversion of this type. This is usually not needed for
+     *                     strings and numeric types.
+     *
+     * @return SQLFilter The current SQL filter.
+     */
+    final public function setParameter($name, $value, $type = null)
+    {
+        if (null === $type) {
+            $type = ParameterTypeInferer::inferType($value);
+        }
+
+        $this->parameters[$name] = array('value' => $value, 'type' => $type);
+
+        // Keep the parameters sorted for the hash
+        ksort($this->parameters);
+
+        // The filter collection of the EM is now dirty
+        $this->em->getFilters()->setFiltersStateDirty();
+
+        return $this;
+    }
+
+    /**
+     * Gets a parameter to use in a query.
+     *
+     * The function is responsible for the right output escaping to use the
+     * value in a query.
+     *
+     * @param string $name Name of the parameter.
+     *
+     * @return string The SQL escaped parameter to use in a query.
+     */
+    final public function getParameter($name)
+    {
+        if (!isset($this->parameters[$name])) {
+            throw new \InvalidArgumentException("Parameter '" . $name . "' does not exist.");
+        }
+
+        return $this->em->getConnection()->quote($this->parameters[$name]['value'], $this->parameters[$name]['type']);
+    }
+
+    /**
+     * Returns as string representation of the SQLFilter parameters (the state).
+     *
+     * @return string String representation of the SQLFilter.
+     */
+    final public function __toString()
+    {
+        return serialize($this->parameters);
+    }
+
+    /**
+     * Gets the SQL query part to add to a query.
+     *
+     * @return string The constraint SQL if there is available, empty string otherwise
+     */
+    abstract public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/FilterCollection.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/FilterCollection.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/FilterCollection.php	(revision 345)
@@ -0,0 +1,198 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\ORM\Configuration,
+    Doctrine\ORM\EntityManager;
+
+/**
+ * Collection class for all the query filters.
+ *
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class FilterCollection
+{
+    /* Filter STATES */
+    /**
+     * A filter object is in CLEAN state when it has no changed parameters.
+     */
+    const FILTERS_STATE_CLEAN  = 1;
+
+    /**
+     * A filter object is in DIRTY state when it has changed parameters.
+     */
+    const FILTERS_STATE_DIRTY = 2;
+
+    /**
+     * The used Configuration.
+     *
+     * @var Doctrine\ORM\Configuration
+     */
+    private $config;
+
+    /**
+     * The EntityManager that "owns" this FilterCollection instance.
+     *
+     * @var Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * Instances of enabled filters.
+     *
+     * @var array
+     */
+    private $enabledFilters = array();
+
+    /**
+     * @var string The filter hash from the last time the query was parsed.
+     */
+    private $filterHash;
+
+    /**
+     * @var integer $state The current state of this filter
+     */
+    private $filtersState = self::FILTERS_STATE_CLEAN;
+
+    /**
+     * Constructor.
+     *
+     * @param EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+        $this->config = $em->getConfiguration();
+    }
+
+    /**
+     * Get all the enabled filters.
+     *
+     * @return array The enabled filters.
+     */
+    public function getEnabledFilters()
+    {
+        return $this->enabledFilters;
+    }
+
+    /**
+     * Enables a filter from the collection.
+     *
+     * @param string $name Name of the filter.
+     *
+     * @throws \InvalidArgumentException If the filter does not exist.
+     *
+     * @return SQLFilter The enabled filter.
+     */
+    public function enable($name)
+    {
+        if (null === $filterClass = $this->config->getFilterClassName($name)) {
+            throw new \InvalidArgumentException("Filter '" . $name . "' does not exist.");
+        }
+
+        if (!isset($this->enabledFilters[$name])) {
+            $this->enabledFilters[$name] = new $filterClass($this->em);
+
+            // Keep the enabled filters sorted for the hash
+            ksort($this->enabledFilters);
+
+            // Now the filter collection is dirty
+            $this->filtersState = self::FILTERS_STATE_DIRTY;
+        }
+
+        return $this->enabledFilters[$name];
+    }
+
+    /**
+     * Disables a filter.
+     *
+     * @param string $name Name of the filter.
+     *
+     * @return SQLFilter The disabled filter.
+     *
+     * @throws \InvalidArgumentException If the filter does not exist.
+     */
+    public function disable($name)
+    {
+        // Get the filter to return it
+        $filter = $this->getFilter($name);
+
+        unset($this->enabledFilters[$name]);
+
+        // Now the filter collection is dirty
+        $this->filtersState = self::FILTERS_STATE_DIRTY;
+
+        return $filter;
+    }
+
+    /**
+     * Get an enabled filter from the collection.
+     *
+     * @param string $name Name of the filter.
+     *
+     * @return SQLFilter The filter.
+     *
+     * @throws \InvalidArgumentException If the filter is not enabled.
+     */
+    public function getFilter($name)
+    {
+        if (!isset($this->enabledFilters[$name])) {
+            throw new \InvalidArgumentException("Filter '" . $name . "' is not enabled.");
+        }
+
+        return $this->enabledFilters[$name];
+    }
+
+    /**
+     * @return boolean True, if the filter collection is clean.
+     */
+    public function isClean()
+    {
+        return self::FILTERS_STATE_CLEAN === $this->filtersState;
+    }
+
+    /**
+     * Generates a string of currently enabled filters to use for the cache id.
+     *
+     * @return string
+     */
+    public function getHash()
+    {
+        // If there are only clean filters, the previous hash can be returned
+        if (self::FILTERS_STATE_CLEAN === $this->filtersState) {
+            return $this->filterHash;
+        }
+
+        $filterHash = '';
+        foreach ($this->enabledFilters as $name => $filter) {
+            $filterHash .= $name . $filter;
+        }
+
+        return $filterHash;
+    }
+
+    /**
+     * Set the filter state to dirty.
+     */
+    public function setFiltersStateDirty()
+    {
+        $this->filtersState = self::FILTERS_STATE_DIRTY;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Lexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Lexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Lexer.php	(revision 345)
@@ -0,0 +1,208 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * Scans a DQL query for tokens.
+ *
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Janne Vanhala <jpvanhal@cc.hut.fi>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class Lexer extends \Doctrine\Common\Lexer
+{
+    // All tokens that are not valid identifiers must be < 100
+    const T_NONE                = 1;
+    const T_INTEGER             = 2;
+    const T_STRING              = 3;
+    const T_INPUT_PARAMETER     = 4;
+    const T_FLOAT               = 5;
+    const T_CLOSE_PARENTHESIS   = 6;
+    const T_OPEN_PARENTHESIS    = 7;
+    const T_COMMA               = 8;
+    const T_DIVIDE              = 9;
+    const T_DOT                 = 10;
+    const T_EQUALS              = 11;
+    const T_GREATER_THAN        = 12;
+    const T_LOWER_THAN          = 13;
+    const T_MINUS               = 14;
+    const T_MULTIPLY            = 15;
+    const T_NEGATE              = 16;
+    const T_PLUS                = 17;
+    const T_OPEN_CURLY_BRACE    = 18;
+    const T_CLOSE_CURLY_BRACE   = 19;
+
+    // All tokens that are also identifiers should be >= 100
+    const T_IDENTIFIER          = 100;
+    const T_ALL                 = 101;
+    const T_AND                 = 102;
+    const T_ANY                 = 103;
+    const T_AS                  = 104;
+    const T_ASC                 = 105;
+    const T_AVG                 = 106;
+    const T_BETWEEN             = 107;
+    const T_BOTH                = 108;
+    const T_BY                  = 109;
+    const T_CASE                = 110;
+    const T_COALESCE            = 111;
+    const T_COUNT               = 112;
+    const T_DELETE              = 113;
+    const T_DESC                = 114;
+    const T_DISTINCT            = 115;
+    const T_ELSE                = 116;
+    const T_EMPTY               = 117;
+    const T_END                 = 118;
+    const T_ESCAPE              = 119;
+    const T_EXISTS              = 120;
+    const T_FALSE               = 121;
+    const T_FROM                = 122;
+    const T_GROUP               = 123;
+    const T_HAVING              = 124;
+    const T_HIDDEN              = 125;
+    const T_IN                  = 126;
+    const T_INDEX               = 127;
+    const T_INNER               = 128;
+    const T_INSTANCE            = 129;
+    const T_IS                  = 130;
+    const T_JOIN                = 131;
+    const T_LEADING             = 132;
+    const T_LEFT                = 133;
+    const T_LIKE                = 134;
+    const T_MAX                 = 135;
+    const T_MEMBER              = 136;
+    const T_MIN                 = 137;
+    const T_NOT                 = 138;
+    const T_NULL                = 139;
+    const T_NULLIF              = 140;
+    const T_OF                  = 141;
+    const T_OR                  = 142;
+    const T_ORDER               = 143;
+    const T_OUTER               = 144;
+    const T_SELECT              = 145;
+    const T_SET                 = 146;
+    const T_SIZE                = 147;
+    const T_SOME                = 148;
+    const T_SUM                 = 149;
+    const T_THEN                = 150;
+    const T_TRAILING            = 151;
+    const T_TRUE                = 152;
+    const T_UPDATE              = 153;
+    const T_WHEN                = 154;
+    const T_WHERE               = 155;
+    const T_WITH                = 156;
+    const T_PARTIAL             = 157;
+    const T_MOD                 = 158;
+
+    /**
+     * Creates a new query scanner object.
+     *
+     * @param string $input a query string
+     */
+    public function __construct($input)
+    {
+        $this->setInput($input);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getCatchablePatterns()
+    {
+        return array(
+            '[a-z_\\\][a-z0-9_\:\\\]*[a-z0-9_]{1}',
+            '(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?',
+            "'(?:[^']|'')*'",
+            '\?[0-9]*|:[a-z]{1}[a-z0-9_]{0,}'
+        );
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getNonCatchablePatterns()
+    {
+        return array('\s+', '(.)');
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getType(&$value)
+    {
+        $type = self::T_NONE;
+
+        switch (true) {
+            // Recognize numeric values
+            case (is_numeric($value)):
+                if (strpos($value, '.') !== false || stripos($value, 'e') !== false) {
+                    return self::T_FLOAT;
+                }
+
+                return self::T_INTEGER;
+
+            // Recognize quoted strings
+            case ($value[0] === "'"):
+                $value = str_replace("''", "'", substr($value, 1, strlen($value) - 2));
+
+                return self::T_STRING;
+
+            // Recognize identifiers
+            case (ctype_alpha($value[0]) || $value[0] === '_'):
+                $name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($value);
+
+                if (defined($name)) {
+                    $type = constant($name);
+
+                    if ($type > 100) {
+                        return $type;
+                    }
+                }
+
+                return self::T_IDENTIFIER;
+
+            // Recognize input parameters
+            case ($value[0] === '?' || $value[0] === ':'):
+                return self::T_INPUT_PARAMETER;
+
+            // Recognize symbols
+            case ($value === '.'): return self::T_DOT;
+            case ($value === ','): return self::T_COMMA;
+            case ($value === '('): return self::T_OPEN_PARENTHESIS;
+            case ($value === ')'): return self::T_CLOSE_PARENTHESIS;
+            case ($value === '='): return self::T_EQUALS;
+            case ($value === '>'): return self::T_GREATER_THAN;
+            case ($value === '<'): return self::T_LOWER_THAN;
+            case ($value === '+'): return self::T_PLUS;
+            case ($value === '-'): return self::T_MINUS;
+            case ($value === '*'): return self::T_MULTIPLY;
+            case ($value === '/'): return self::T_DIVIDE;
+            case ($value === '!'): return self::T_NEGATE;
+            case ($value === '{'): return self::T_OPEN_CURLY_BRACE;
+            case ($value === '}'): return self::T_CLOSE_CURLY_BRACE;
+
+            // Default
+            default:
+                // Do nothing
+        }
+
+        return $type;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParameterTypeInferer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParameterTypeInferer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParameterTypeInferer.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Types\Type;
+
+/**
+ * Provides an enclosed support for parameter infering.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ParameterTypeInferer
+{
+    /**
+     * Infer type of a given value, returning a compatible constant:
+     * - Type (\Doctrine\DBAL\Types\Type::*)
+     * - Connection (\Doctrine\DBAL\Connection::PARAM_*)
+     *
+     * @param mixed $value Parameter value
+     *
+     * @return mixed Parameter type constant
+     */
+    public static function inferType($value)
+    {
+        switch (true) {
+            case is_integer($value):
+                return Type::INTEGER;
+
+            case ($value instanceof \DateTime):
+                return Type::DATETIME;
+
+            case is_array($value):
+                $key = key($value);
+
+                if (is_integer($value[$key])) {
+                    return Connection::PARAM_INT_ARRAY;
+                }
+
+                return Connection::PARAM_STR_ARRAY;
+
+            default:
+                // Do nothing
+                break;
+        }
+
+        return \PDO::PARAM_STR;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Parser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Parser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Parser.php	(revision 345)
@@ -0,0 +1,3093 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHARNTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\ORM\Query;
+use Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * An LL(*) recursive-descent parser for the context-free grammar of the Doctrine Query Language.
+ * Parses a DQL query, reports any errors in it, and generates an AST.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Janne Vanhala <jpvanhal@cc.hut.fi>
+ */
+class Parser
+{
+    /** READ-ONLY: Maps BUILT-IN string function names to AST class names. */
+    private static $_STRING_FUNCTIONS = array(
+        'concat'    => 'Doctrine\ORM\Query\AST\Functions\ConcatFunction',
+        'substring' => 'Doctrine\ORM\Query\AST\Functions\SubstringFunction',
+        'trim'      => 'Doctrine\ORM\Query\AST\Functions\TrimFunction',
+        'lower'     => 'Doctrine\ORM\Query\AST\Functions\LowerFunction',
+        'upper'     => 'Doctrine\ORM\Query\AST\Functions\UpperFunction',
+        'identity'  => 'Doctrine\ORM\Query\AST\Functions\IdentityFunction',
+    );
+
+    /** READ-ONLY: Maps BUILT-IN numeric function names to AST class names. */
+    private static $_NUMERIC_FUNCTIONS = array(
+        'length'    => 'Doctrine\ORM\Query\AST\Functions\LengthFunction',
+        'locate'    => 'Doctrine\ORM\Query\AST\Functions\LocateFunction',
+        'abs'       => 'Doctrine\ORM\Query\AST\Functions\AbsFunction',
+        'sqrt'      => 'Doctrine\ORM\Query\AST\Functions\SqrtFunction',
+        'mod'       => 'Doctrine\ORM\Query\AST\Functions\ModFunction',
+        'size'      => 'Doctrine\ORM\Query\AST\Functions\SizeFunction',
+        'date_diff' => 'Doctrine\ORM\Query\AST\Functions\DateDiffFunction',
+        'bit_and'   => 'Doctrine\ORM\Query\AST\Functions\BitAndFunction',
+        'bit_or'    => 'Doctrine\ORM\Query\AST\Functions\BitOrFunction',
+    );
+
+    /** READ-ONLY: Maps BUILT-IN datetime function names to AST class names. */
+    private static $_DATETIME_FUNCTIONS = array(
+        'current_date'      => 'Doctrine\ORM\Query\AST\Functions\CurrentDateFunction',
+        'current_time'      => 'Doctrine\ORM\Query\AST\Functions\CurrentTimeFunction',
+        'current_timestamp' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimestampFunction',
+        'date_add'          => 'Doctrine\ORM\Query\AST\Functions\DateAddFunction',
+        'date_sub'          => 'Doctrine\ORM\Query\AST\Functions\DateSubFunction',
+    );
+
+    /**
+     * Expressions that were encountered during parsing of identifiers and expressions
+     * and still need to be validated.
+     */
+    private $_deferredIdentificationVariables = array();
+    private $_deferredPartialObjectExpressions = array();
+    private $_deferredPathExpressions = array();
+    private $_deferredResultVariables = array();
+
+    /**
+     * The lexer.
+     *
+     * @var \Doctrine\ORM\Query\Lexer
+     */
+    private $_lexer;
+
+    /**
+     * The parser result.
+     *
+     * @var \Doctrine\ORM\Query\ParserResult
+     */
+    private $_parserResult;
+
+    /**
+     * The EntityManager.
+     *
+     * @var EnityManager
+     */
+    private $_em;
+
+    /**
+     * The Query to parse.
+     *
+     * @var Query
+     */
+    private $_query;
+
+    /**
+     * Map of declared query components in the parsed query.
+     *
+     * @var array
+     */
+    private $_queryComponents = array();
+
+    /**
+     * Keeps the nesting level of defined ResultVariables
+     *
+     * @var integer
+     */
+    private $_nestingLevel = 0;
+
+    /**
+     * Any additional custom tree walkers that modify the AST.
+     *
+     * @var array
+     */
+    private $_customTreeWalkers = array();
+
+    /**
+     * The custom last tree walker, if any, that is responsible for producing the output.
+     *
+     * @var TreeWalker
+     */
+    private $_customOutputWalker;
+
+    /**
+     * @var array
+     */
+    private $_identVariableExpressions = array();
+
+    /**
+     * Creates a new query parser object.
+     *
+     * @param Query $query The Query to parse.
+     */
+    public function __construct(Query $query)
+    {
+        $this->_query        = $query;
+        $this->_em           = $query->getEntityManager();
+        $this->_lexer        = new Lexer($query->getDql());
+        $this->_parserResult = new ParserResult();
+    }
+
+    /**
+     * Sets a custom tree walker that produces output.
+     * This tree walker will be run last over the AST, after any other walkers.
+     *
+     * @param string $className
+     */
+    public function setCustomOutputTreeWalker($className)
+    {
+        $this->_customOutputWalker = $className;
+    }
+
+    /**
+     * Adds a custom tree walker for modifying the AST.
+     *
+     * @param string $className
+     */
+    public function addCustomTreeWalker($className)
+    {
+        $this->_customTreeWalkers[] = $className;
+    }
+
+    /**
+     * Gets the lexer used by the parser.
+     *
+     * @return \Doctrine\ORM\Query\Lexer
+     */
+    public function getLexer()
+    {
+        return $this->_lexer;
+    }
+
+    /**
+     * Gets the ParserResult that is being filled with information during parsing.
+     *
+     * @return \Doctrine\ORM\Query\ParserResult
+     */
+    public function getParserResult()
+    {
+        return $this->_parserResult;
+    }
+
+    /**
+     * Gets the EntityManager used by the parser.
+     *
+     * @return EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * Parse and build AST for the given Query.
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectStatement |
+     *         \Doctrine\ORM\Query\AST\UpdateStatement |
+     *         \Doctrine\ORM\Query\AST\DeleteStatement
+     */
+    public function getAST()
+    {
+        // Parse & build AST
+        $AST = $this->QueryLanguage();
+
+        // Process any deferred validations of some nodes in the AST.
+        // This also allows post-processing of the AST for modification purposes.
+        $this->_processDeferredIdentificationVariables();
+
+        if ($this->_deferredPartialObjectExpressions) {
+            $this->_processDeferredPartialObjectExpressions();
+        }
+
+        if ($this->_deferredPathExpressions) {
+            $this->_processDeferredPathExpressions($AST);
+        }
+
+        if ($this->_deferredResultVariables) {
+            $this->_processDeferredResultVariables();
+        }
+
+        $this->_processRootEntityAliasSelected();
+
+        // TODO: Is there a way to remove this? It may impact the mixed hydration resultset a lot!
+        $this->fixIdentificationVariableOrder($AST);
+
+        return $AST;
+    }
+
+    /**
+     * Attempts to match the given token with the current lookahead token.
+     *
+     * If they match, updates the lookahead token; otherwise raises a syntax
+     * error.
+     *
+     * @param int token type
+     * @return void
+     * @throws QueryException If the tokens dont match.
+     */
+    public function match($token)
+    {
+        $lookaheadType = $this->_lexer->lookahead['type'];
+
+        // short-circuit on first condition, usually types match
+        if ($lookaheadType !== $token && $token !== Lexer::T_IDENTIFIER && $lookaheadType <= Lexer::T_IDENTIFIER) {
+            $this->syntaxError($this->_lexer->getLiteral($token));
+        }
+
+        $this->_lexer->moveNext();
+    }
+
+    /**
+     * Free this parser enabling it to be reused
+     *
+     * @param boolean $deep     Whether to clean peek and reset errors
+     * @param integer $position Position to reset
+     */
+    public function free($deep = false, $position = 0)
+    {
+        // WARNING! Use this method with care. It resets the scanner!
+        $this->_lexer->resetPosition($position);
+
+        // Deep = true cleans peek and also any previously defined errors
+        if ($deep) {
+            $this->_lexer->resetPeek();
+        }
+
+        $this->_lexer->token = null;
+        $this->_lexer->lookahead = null;
+    }
+
+    /**
+     * Parses a query string.
+     *
+     * @return ParserResult
+     */
+    public function parse()
+    {
+        $AST = $this->getAST();
+
+        if (($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) {
+            $this->_customTreeWalkers = $customWalkers;
+        }
+
+        if (($customOutputWalker = $this->_query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER)) !== false) {
+            $this->_customOutputWalker = $customOutputWalker;
+        }
+
+        // Run any custom tree walkers over the AST
+        if ($this->_customTreeWalkers) {
+            $treeWalkerChain = new TreeWalkerChain($this->_query, $this->_parserResult, $this->_queryComponents);
+
+            foreach ($this->_customTreeWalkers as $walker) {
+                $treeWalkerChain->addTreeWalker($walker);
+            }
+
+            switch (true) {
+                case ($AST instanceof AST\UpdateStatement):
+                    $treeWalkerChain->walkUpdateStatement($AST);
+                    break;
+
+                case ($AST instanceof AST\DeleteStatement):
+                    $treeWalkerChain->walkDeleteStatement($AST);
+                    break;
+
+                case ($AST instanceof AST\SelectStatement):
+                default:
+                    $treeWalkerChain->walkSelectStatement($AST);
+            }
+        }
+
+        $outputWalkerClass = $this->_customOutputWalker ?: __NAMESPACE__ . '\SqlWalker';
+        $outputWalker      = new $outputWalkerClass($this->_query, $this->_parserResult, $this->_queryComponents);
+
+        // Assign an SQL executor to the parser result
+        $this->_parserResult->setSqlExecutor($outputWalker->getExecutor($AST));
+
+        return $this->_parserResult;
+    }
+
+    /**
+     * Fix order of identification variables.
+     *
+     * They have to appear in the select clause in the same order as the
+     * declarations (from ... x join ... y join ... z ...) appear in the query
+     * as the hydration process relies on that order for proper operation.
+     *
+     * @param AST\SelectStatement|AST\DeleteStatement|AST\UpdateStatement $AST
+     * @return void
+     */
+    private function fixIdentificationVariableOrder($AST)
+    {
+        if (count($this->_identVariableExpressions) <= 1) {
+            return;
+        }
+
+        foreach ($this->_queryComponents as $dqlAlias => $qComp) {
+            if ( ! isset($this->_identVariableExpressions[$dqlAlias])) {
+                continue;
+            }
+
+            $expr = $this->_identVariableExpressions[$dqlAlias];
+            $key  = array_search($expr, $AST->selectClause->selectExpressions);
+
+            unset($AST->selectClause->selectExpressions[$key]);
+
+            $AST->selectClause->selectExpressions[] = $expr;
+        }
+    }
+
+    /**
+     * Generates a new syntax error.
+     *
+     * @param string $expected Expected string.
+     * @param array $token Got token.
+     *
+     * @throws \Doctrine\ORM\Query\QueryException
+     */
+    public function syntaxError($expected = '', $token = null)
+    {
+        if ($token === null) {
+            $token = $this->_lexer->lookahead;
+        }
+
+        $tokenPos = (isset($token['position'])) ? $token['position'] : '-1';
+
+        $message  = "line 0, col {$tokenPos}: Error: ";
+        $message .= ($expected !== '') ? "Expected {$expected}, got " : 'Unexpected ';
+        $message .= ($this->_lexer->lookahead === null) ? 'end of string.' : "'{$token['value']}'";
+
+        throw QueryException::syntaxError($message);
+    }
+
+    /**
+     * Generates a new semantical error.
+     *
+     * @param string $message Optional message.
+     * @param array $token Optional token.
+     *
+     * @throws \Doctrine\ORM\Query\QueryException
+     */
+    public function semanticalError($message = '', $token = null)
+    {
+        if ($token === null) {
+            $token = $this->_lexer->lookahead;
+        }
+
+        // Minimum exposed chars ahead of token
+        $distance = 12;
+
+        // Find a position of a final word to display in error string
+        $dql    = $this->_query->getDql();
+        $length = strlen($dql);
+        $pos    = $token['position'] + $distance;
+        $pos    = strpos($dql, ' ', ($length > $pos) ? $pos : $length);
+        $length = ($pos !== false) ? $pos - $token['position'] : $distance;
+
+        $tokenPos = (isset($token['position']) && $token['position'] > 0) ? $token['position'] : '-1';
+        $tokenStr = substr($dql, $token['position'], $length);
+
+        // Building informative message
+        $message = 'line 0, col ' . $tokenPos . " near '" . $tokenStr . "': Error: " . $message;
+
+        throw QueryException::semanticalError($message);
+    }
+
+    /**
+     * Peeks beyond the specified token and returns the first token after that one.
+     *
+     * @param array $token
+     * @return array
+     */
+    private function _peekBeyond($token)
+    {
+        $peek = $this->_lexer->peek();
+
+        while ($peek['value'] != $token) {
+            $peek = $this->_lexer->peek();
+        }
+
+        $peek = $this->_lexer->peek();
+        $this->_lexer->resetPeek();
+
+        return $peek;
+    }
+
+    /**
+     * Peek beyond the matched closing parenthesis and return the first token after that one.
+     *
+     * @return array
+     */
+    private function _peekBeyondClosingParenthesis()
+    {
+        $token = $this->_lexer->peek();
+        $numUnmatched = 1;
+
+        while ($numUnmatched > 0 && $token !== null) {
+            switch ($token['type']) {
+                case Lexer::T_OPEN_PARENTHESIS:
+                    ++$numUnmatched;
+                    break;
+
+                case Lexer::T_CLOSE_PARENTHESIS:
+                    --$numUnmatched;
+                    break;
+
+                default:
+                    // Do nothing
+            }
+
+            $token = $this->_lexer->peek();
+        }
+
+        $this->_lexer->resetPeek();
+
+        return $token;
+    }
+
+    /**
+     * Checks if the given token indicates a mathematical operator.
+     *
+     * @return boolean TRUE if the token is a mathematical operator, FALSE otherwise.
+     */
+    private function _isMathOperator($token)
+    {
+        return in_array($token['type'], array(Lexer::T_PLUS, Lexer::T_MINUS, Lexer::T_DIVIDE, Lexer::T_MULTIPLY));
+    }
+
+    /**
+     * Checks if the next-next (after lookahead) token starts a function.
+     *
+     * @return boolean TRUE if the next-next tokens start a function, FALSE otherwise.
+     */
+    private function _isFunction()
+    {
+        $peek     = $this->_lexer->peek();
+        $nextpeek = $this->_lexer->peek();
+
+        $this->_lexer->resetPeek();
+
+        // We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function
+        return ($peek['type'] === Lexer::T_OPEN_PARENTHESIS && $nextpeek['type'] !== Lexer::T_SELECT);
+    }
+
+    /**
+     * Checks whether the given token type indicates an aggregate function.
+     *
+     * @return boolean TRUE if the token type is an aggregate function, FALSE otherwise.
+     */
+    private function _isAggregateFunction($tokenType)
+    {
+        return in_array($tokenType, array(Lexer::T_AVG, Lexer::T_MIN, Lexer::T_MAX, Lexer::T_SUM, Lexer::T_COUNT));
+    }
+
+    /**
+     * Checks whether the current lookahead token of the lexer has the type T_ALL, T_ANY or T_SOME.
+     *
+     * @return boolean
+     */
+    private function _isNextAllAnySome()
+    {
+        return in_array($this->_lexer->lookahead['type'], array(Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME));
+    }
+
+    /**
+     * Validates that the given <tt>IdentificationVariable</tt> is semantically correct.
+     * It must exist in query components list.
+     *
+     * @return void
+     */
+    private function _processDeferredIdentificationVariables()
+    {
+        foreach ($this->_deferredIdentificationVariables as $deferredItem) {
+            $identVariable = $deferredItem['expression'];
+
+            // Check if IdentificationVariable exists in queryComponents
+            if ( ! isset($this->_queryComponents[$identVariable])) {
+                $this->semanticalError(
+                    "'$identVariable' is not defined.", $deferredItem['token']
+                );
+            }
+
+            $qComp = $this->_queryComponents[$identVariable];
+
+            // Check if queryComponent points to an AbstractSchemaName or a ResultVariable
+            if ( ! isset($qComp['metadata'])) {
+                $this->semanticalError(
+                    "'$identVariable' does not point to a Class.", $deferredItem['token']
+                );
+            }
+
+            // Validate if identification variable nesting level is lower or equal than the current one
+            if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) {
+                $this->semanticalError(
+                    "'$identVariable' is used outside the scope of its declaration.", $deferredItem['token']
+                );
+            }
+        }
+    }
+
+    /**
+     * Validates that the given <tt>PartialObjectExpression</tt> is semantically correct.
+     * It must exist in query components list.
+     *
+     * @return void
+     */
+    private function _processDeferredPartialObjectExpressions()
+    {
+        foreach ($this->_deferredPartialObjectExpressions as $deferredItem) {
+            $expr = $deferredItem['expression'];
+            $class = $this->_queryComponents[$expr->identificationVariable]['metadata'];
+
+            foreach ($expr->partialFieldSet as $field) {
+                if (isset($class->fieldMappings[$field])) {
+                	continue;
+                }
+
+                $this->semanticalError(
+                    "There is no mapped field named '$field' on class " . $class->name . ".", $deferredItem['token']
+                );
+            }
+
+            if (array_intersect($class->identifier, $expr->partialFieldSet) != $class->identifier) {
+                $this->semanticalError(
+                    "The partial field selection of class " . $class->name . " must contain the identifier.",
+                    $deferredItem['token']
+                );
+            }
+        }
+    }
+
+    /**
+     * Validates that the given <tt>ResultVariable</tt> is semantically correct.
+     * It must exist in query components list.
+     *
+     * @return void
+     */
+    private function _processDeferredResultVariables()
+    {
+        foreach ($this->_deferredResultVariables as $deferredItem) {
+            $resultVariable = $deferredItem['expression'];
+
+            // Check if ResultVariable exists in queryComponents
+            if ( ! isset($this->_queryComponents[$resultVariable])) {
+                $this->semanticalError(
+                    "'$resultVariable' is not defined.", $deferredItem['token']
+                );
+            }
+
+            $qComp = $this->_queryComponents[$resultVariable];
+
+            // Check if queryComponent points to an AbstractSchemaName or a ResultVariable
+            if ( ! isset($qComp['resultVariable'])) {
+                $this->semanticalError(
+                    "'$identVariable' does not point to a ResultVariable.", $deferredItem['token']
+                );
+            }
+
+            // Validate if identification variable nesting level is lower or equal than the current one
+            if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) {
+                $this->semanticalError(
+                    "'$resultVariable' is used outside the scope of its declaration.", $deferredItem['token']
+                );
+            }
+        }
+    }
+
+    /**
+     * Validates that the given <tt>PathExpression</tt> is semantically correct for grammar rules:
+     *
+     * AssociationPathExpression             ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
+     * SingleValuedPathExpression            ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
+     * StateFieldPathExpression              ::= IdentificationVariable "." StateField
+     * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
+     * CollectionValuedPathExpression        ::= IdentificationVariable "." CollectionValuedAssociationField
+     *
+     * @param array $deferredItem
+     * @param mixed $AST
+     */
+    private function _processDeferredPathExpressions($AST)
+    {
+        foreach ($this->_deferredPathExpressions as $deferredItem) {
+            $pathExpression = $deferredItem['expression'];
+
+            $qComp = $this->_queryComponents[$pathExpression->identificationVariable];
+            $class = $qComp['metadata'];
+
+            if (($field = $pathExpression->field) === null) {
+                $field = $pathExpression->field = $class->identifier[0];
+            }
+
+            // Check if field or association exists
+            if ( ! isset($class->associationMappings[$field]) && ! isset($class->fieldMappings[$field])) {
+                $this->semanticalError(
+                    'Class ' . $class->name . ' has no field or association named ' . $field,
+                    $deferredItem['token']
+                );
+            }
+
+            $fieldType = AST\PathExpression::TYPE_STATE_FIELD;
+
+            if (isset($class->associationMappings[$field])) {
+                $assoc = $class->associationMappings[$field];
+
+                $fieldType = ($assoc['type'] & ClassMetadata::TO_ONE)
+                	? AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION
+                	: AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION;
+            }
+
+            // Validate if PathExpression is one of the expected types
+            $expectedType = $pathExpression->expectedType;
+
+            if ( ! ($expectedType & $fieldType)) {
+                // We need to recognize which was expected type(s)
+                $expectedStringTypes = array();
+
+                // Validate state field type
+                if ($expectedType & AST\PathExpression::TYPE_STATE_FIELD) {
+                    $expectedStringTypes[] = 'StateFieldPathExpression';
+                }
+
+                // Validate single valued association (*-to-one)
+                if ($expectedType & AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION) {
+                    $expectedStringTypes[] = 'SingleValuedAssociationField';
+                }
+
+                // Validate single valued association (*-to-many)
+                if ($expectedType & AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) {
+                    $expectedStringTypes[] = 'CollectionValuedAssociationField';
+                }
+
+                // Build the error message
+                $semanticalError  = 'Invalid PathExpression. ';
+                $semanticalError .= (count($expectedStringTypes) == 1)
+                    ? 'Must be a ' . $expectedStringTypes[0] . '.'
+                    : implode(' or ', $expectedStringTypes) . ' expected.';
+
+                $this->semanticalError($semanticalError, $deferredItem['token']);
+            }
+
+            // We need to force the type in PathExpression
+            $pathExpression->type = $fieldType;
+        }
+    }
+
+    private function _processRootEntityAliasSelected()
+    {
+        if ( ! count($this->_identVariableExpressions)) {
+            return;
+        }
+
+        $foundRootEntity = false;
+
+        foreach ($this->_identVariableExpressions AS $dqlAlias => $expr) {
+            if (isset($this->_queryComponents[$dqlAlias]) && $this->_queryComponents[$dqlAlias]['parent'] === null) {
+                $foundRootEntity = true;
+            }
+        }
+
+        if ( ! $foundRootEntity) {
+            $this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.');
+        }
+    }
+
+    /**
+     * QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectStatement |
+     *         \Doctrine\ORM\Query\AST\UpdateStatement |
+     *         \Doctrine\ORM\Query\AST\DeleteStatement
+     */
+    public function QueryLanguage()
+    {
+        $this->_lexer->moveNext();
+
+        switch ($this->_lexer->lookahead['type']) {
+            case Lexer::T_SELECT:
+                $statement = $this->SelectStatement();
+                break;
+
+            case Lexer::T_UPDATE:
+                $statement = $this->UpdateStatement();
+                break;
+
+            case Lexer::T_DELETE:
+                $statement = $this->DeleteStatement();
+                break;
+
+            default:
+                $this->syntaxError('SELECT, UPDATE or DELETE');
+                break;
+        }
+
+        // Check for end of string
+        if ($this->_lexer->lookahead !== null) {
+            $this->syntaxError('end of string');
+        }
+
+        return $statement;
+    }
+
+    /**
+     * SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectStatement
+     */
+    public function SelectStatement()
+    {
+        $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause());
+
+        $selectStatement->whereClause   = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null;
+        $selectStatement->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null;
+        $selectStatement->havingClause  = $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null;
+        $selectStatement->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null;
+
+        return $selectStatement;
+    }
+
+    /**
+     * UpdateStatement ::= UpdateClause [WhereClause]
+     *
+     * @return \Doctrine\ORM\Query\AST\UpdateStatement
+     */
+    public function UpdateStatement()
+    {
+        $updateStatement = new AST\UpdateStatement($this->UpdateClause());
+
+        $updateStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null;
+
+        return $updateStatement;
+    }
+
+    /**
+     * DeleteStatement ::= DeleteClause [WhereClause]
+     *
+     * @return \Doctrine\ORM\Query\AST\DeleteStatement
+     */
+    public function DeleteStatement()
+    {
+        $deleteStatement = new AST\DeleteStatement($this->DeleteClause());
+
+        $deleteStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null;
+
+        return $deleteStatement;
+    }
+
+    /**
+     * IdentificationVariable ::= identifier
+     *
+     * @return string
+     */
+    public function IdentificationVariable()
+    {
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $identVariable = $this->_lexer->token['value'];
+
+        $this->_deferredIdentificationVariables[] = array(
+            'expression'   => $identVariable,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $this->_lexer->token,
+        );
+
+        return $identVariable;
+    }
+
+    /**
+     * AliasIdentificationVariable = identifier
+     *
+     * @return string
+     */
+    public function AliasIdentificationVariable()
+    {
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $aliasIdentVariable = $this->_lexer->token['value'];
+        $exists = isset($this->_queryComponents[$aliasIdentVariable]);
+
+        if ($exists) {
+            $this->semanticalError("'$aliasIdentVariable' is already defined.", $this->_lexer->token);
+        }
+
+        return $aliasIdentVariable;
+    }
+
+    /**
+     * AbstractSchemaName ::= identifier
+     *
+     * @return string
+     */
+    public function AbstractSchemaName()
+    {
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $schemaName = ltrim($this->_lexer->token['value'], '\\');
+
+        if (strrpos($schemaName, ':') !== false) {
+            list($namespaceAlias, $simpleClassName) = explode(':', $schemaName);
+
+            $schemaName = $this->_em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
+        }
+
+        $exists = class_exists($schemaName, true);
+
+        if ( ! $exists) {
+            $this->semanticalError("Class '$schemaName' is not defined.", $this->_lexer->token);
+        }
+
+        return $schemaName;
+    }
+
+    /**
+     * AliasResultVariable ::= identifier
+     *
+     * @return string
+     */
+    public function AliasResultVariable()
+    {
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $resultVariable = $this->_lexer->token['value'];
+        $exists = isset($this->_queryComponents[$resultVariable]);
+
+        if ($exists) {
+            $this->semanticalError("'$resultVariable' is already defined.", $this->_lexer->token);
+        }
+
+        return $resultVariable;
+    }
+
+    /**
+     * ResultVariable ::= identifier
+     *
+     * @return string
+     */
+    public function ResultVariable()
+    {
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $resultVariable = $this->_lexer->token['value'];
+
+        // Defer ResultVariable validation
+        $this->_deferredResultVariables[] = array(
+            'expression'   => $resultVariable,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $this->_lexer->token,
+        );
+
+        return $resultVariable;
+    }
+
+    /**
+     * JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField)
+     *
+     * @return \Doctrine\ORM\Query\AST\JoinAssociationPathExpression
+     */
+    public function JoinAssociationPathExpression()
+    {
+        $token         = $this->_lexer->lookahead;
+        $identVariable = $this->IdentificationVariable();
+
+        if ( ! isset($this->_queryComponents[$identVariable])) {
+            $this->semanticalError(
+                'Identification Variable ' . $identVariable .' used in join path expression but was not defined before.'
+            );
+        }
+
+        $this->match(Lexer::T_DOT);
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $field = $this->_lexer->token['value'];
+
+        // Validate association field
+        $qComp = $this->_queryComponents[$identVariable];
+        $class = $qComp['metadata'];
+
+        if ( ! isset($class->associationMappings[$field])) {
+            $this->semanticalError('Class ' . $class->name . ' has no association named ' . $field);
+        }
+
+        return new AST\JoinAssociationPathExpression($identVariable, $field);
+    }
+
+    /**
+     * Parses an arbitrary path expression and defers semantical validation
+     * based on expected types.
+     *
+     * PathExpression ::= IdentificationVariable "." identifier
+     *
+     * @param integer $expectedTypes
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function PathExpression($expectedTypes)
+    {
+        $token = $this->_lexer->lookahead;
+        $identVariable = $this->IdentificationVariable();
+        $field = null;
+
+        if ($this->_lexer->isNextToken(Lexer::T_DOT)) {
+            $this->match(Lexer::T_DOT);
+            $this->match(Lexer::T_IDENTIFIER);
+
+            $field = $this->_lexer->token['value'];
+        }
+
+        // Creating AST node
+        $pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $field);
+
+        // Defer PathExpression validation if requested to be defered
+        $this->_deferredPathExpressions[] = array(
+            'expression'   => $pathExpr,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $this->_lexer->token,
+        );
+
+        return $pathExpr;
+    }
+
+    /**
+     * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function AssociationPathExpression()
+    {
+        return $this->PathExpression(
+            AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION |
+            AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION
+        );
+    }
+
+    /**
+     * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function SingleValuedPathExpression()
+    {
+        return $this->PathExpression(
+            AST\PathExpression::TYPE_STATE_FIELD |
+            AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION
+        );
+    }
+
+    /**
+     * StateFieldPathExpression ::= IdentificationVariable "." StateField
+     *
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function StateFieldPathExpression()
+    {
+        return $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD);
+    }
+
+    /**
+     * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
+     *
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function SingleValuedAssociationPathExpression()
+    {
+        return $this->PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION);
+    }
+
+    /**
+     * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
+     *
+     * @return \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function CollectionValuedPathExpression()
+    {
+        return $this->PathExpression(AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION);
+    }
+
+    /**
+     * SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectClause
+     */
+    public function SelectClause()
+    {
+        $isDistinct = false;
+        $this->match(Lexer::T_SELECT);
+
+        // Check for DISTINCT
+        if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) {
+            $this->match(Lexer::T_DISTINCT);
+
+            $isDistinct = true;
+        }
+
+        // Process SelectExpressions (1..N)
+        $selectExpressions = array();
+        $selectExpressions[] = $this->SelectExpression();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $selectExpressions[] = $this->SelectExpression();
+        }
+
+        return new AST\SelectClause($selectExpressions, $isDistinct);
+    }
+
+    /**
+     * SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\SimpleSelectClause
+     */
+    public function SimpleSelectClause()
+    {
+        $isDistinct = false;
+        $this->match(Lexer::T_SELECT);
+
+        if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) {
+            $this->match(Lexer::T_DISTINCT);
+
+            $isDistinct = true;
+        }
+
+        return new AST\SimpleSelectClause($this->SimpleSelectExpression(), $isDistinct);
+    }
+
+    /**
+     * UpdateClause ::= "UPDATE" AbstractSchemaName ["AS"] AliasIdentificationVariable "SET" UpdateItem {"," UpdateItem}*
+     *
+     * @return \Doctrine\ORM\Query\AST\UpdateClause
+     */
+    public function UpdateClause()
+    {
+        $this->match(Lexer::T_UPDATE);
+        $token = $this->_lexer->lookahead;
+        $abstractSchemaName = $this->AbstractSchemaName();
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        $aliasIdentificationVariable = $this->AliasIdentificationVariable();
+
+        $class = $this->_em->getClassMetadata($abstractSchemaName);
+
+        // Building queryComponent
+        $queryComponent = array(
+            'metadata'     => $class,
+            'parent'       => null,
+            'relation'     => null,
+            'map'          => null,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $token,
+        );
+
+        $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent;
+
+        $this->match(Lexer::T_SET);
+
+        $updateItems = array();
+        $updateItems[] = $this->UpdateItem();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $updateItems[] = $this->UpdateItem();
+        }
+
+        $updateClause = new AST\UpdateClause($abstractSchemaName, $updateItems);
+        $updateClause->aliasIdentificationVariable = $aliasIdentificationVariable;
+
+        return $updateClause;
+    }
+
+    /**
+     * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName ["AS"] AliasIdentificationVariable
+     *
+     * @return \Doctrine\ORM\Query\AST\DeleteClause
+     */
+    public function DeleteClause()
+    {
+        $this->match(Lexer::T_DELETE);
+
+        if ($this->_lexer->isNextToken(Lexer::T_FROM)) {
+            $this->match(Lexer::T_FROM);
+        }
+
+        $token = $this->_lexer->lookahead;
+        $deleteClause = new AST\DeleteClause($this->AbstractSchemaName());
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        $aliasIdentificationVariable = $this->AliasIdentificationVariable();
+
+        $deleteClause->aliasIdentificationVariable = $aliasIdentificationVariable;
+        $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
+
+        // Building queryComponent
+        $queryComponent = array(
+            'metadata'     => $class,
+            'parent'       => null,
+            'relation'     => null,
+            'map'          => null,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $token,
+        );
+
+        $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent;
+
+        return $deleteClause;
+    }
+
+    /**
+     * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}*
+     *
+     * @return \Doctrine\ORM\Query\AST\FromClause
+     */
+    public function FromClause()
+    {
+        $this->match(Lexer::T_FROM);
+
+        $identificationVariableDeclarations = array();
+        $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration();
+        }
+
+        return new AST\FromClause($identificationVariableDeclarations);
+    }
+
+    /**
+     * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}*
+     *
+     * @return \Doctrine\ORM\Query\AST\SubselectFromClause
+     */
+    public function SubselectFromClause()
+    {
+        $this->match(Lexer::T_FROM);
+
+        $identificationVariables = array();
+        $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration();
+        }
+
+        return new AST\SubselectFromClause($identificationVariables);
+    }
+
+    /**
+     * WhereClause ::= "WHERE" ConditionalExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\WhereClause
+     */
+    public function WhereClause()
+    {
+        $this->match(Lexer::T_WHERE);
+
+        return new AST\WhereClause($this->ConditionalExpression());
+    }
+
+    /**
+     * HavingClause ::= "HAVING" ConditionalExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\HavingClause
+     */
+    public function HavingClause()
+    {
+        $this->match(Lexer::T_HAVING);
+
+        return new AST\HavingClause($this->ConditionalExpression());
+    }
+
+    /**
+     * GroupByClause ::= "GROUP" "BY" GroupByItem {"," GroupByItem}*
+     *
+     * @return \Doctrine\ORM\Query\AST\GroupByClause
+     */
+    public function GroupByClause()
+    {
+        $this->match(Lexer::T_GROUP);
+        $this->match(Lexer::T_BY);
+
+        $groupByItems = array($this->GroupByItem());
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $groupByItems[] = $this->GroupByItem();
+        }
+
+        return new AST\GroupByClause($groupByItems);
+    }
+
+    /**
+     * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
+     *
+     * @return \Doctrine\ORM\Query\AST\OrderByClause
+     */
+    public function OrderByClause()
+    {
+        $this->match(Lexer::T_ORDER);
+        $this->match(Lexer::T_BY);
+
+        $orderByItems = array();
+        $orderByItems[] = $this->OrderByItem();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $orderByItems[] = $this->OrderByItem();
+        }
+
+        return new AST\OrderByClause($orderByItems);
+    }
+
+    /**
+     * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
+     *
+     * @return \Doctrine\ORM\Query\AST\Subselect
+     */
+    public function Subselect()
+    {
+        // Increase query nesting level
+        $this->_nestingLevel++;
+
+        $subselect = new AST\Subselect($this->SimpleSelectClause(), $this->SubselectFromClause());
+
+        $subselect->whereClause   = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null;
+        $subselect->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null;
+        $subselect->havingClause  = $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null;
+        $subselect->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null;
+
+        // Decrease query nesting level
+        $this->_nestingLevel--;
+
+        return $subselect;
+    }
+
+    /**
+     * UpdateItem ::= SingleValuedPathExpression "=" NewValue
+     *
+     * @return \Doctrine\ORM\Query\AST\UpdateItem
+     */
+    public function UpdateItem()
+    {
+        $pathExpr = $this->SingleValuedPathExpression();
+
+        $this->match(Lexer::T_EQUALS);
+
+        $updateItem = new AST\UpdateItem($pathExpr, $this->NewValue());
+
+        return $updateItem;
+    }
+
+    /**
+     * GroupByItem ::= IdentificationVariable | ResultVariable | SingleValuedPathExpression
+     *
+     * @return string | \Doctrine\ORM\Query\AST\PathExpression
+     */
+    public function GroupByItem()
+    {
+        // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression
+        $glimpse = $this->_lexer->glimpse();
+
+        if ($glimpse['type'] === Lexer::T_DOT) {
+            return $this->SingleValuedPathExpression();
+        }
+
+        // Still need to decide between IdentificationVariable or ResultVariable
+        $lookaheadValue = $this->_lexer->lookahead['value'];
+
+        if ( ! isset($this->_queryComponents[$lookaheadValue])) {
+            $this->semanticalError('Cannot group by undefined identification or result variable.');
+        }
+
+        return (isset($this->_queryComponents[$lookaheadValue]['metadata']))
+            ? $this->IdentificationVariable()
+            : $this->ResultVariable();
+    }
+
+    /**
+     * OrderByItem ::= (ResultVariable | SingleValuedPathExpression) ["ASC" | "DESC"]
+     *
+     * @return \Doctrine\ORM\Query\AST\OrderByItem
+     */
+    public function OrderByItem()
+    {
+        $type = 'ASC';
+
+        // We need to check if we are in a ResultVariable or StateFieldPathExpression
+        $glimpse = $this->_lexer->glimpse();
+        $expr    = ($glimpse['type'] != Lexer::T_DOT) ? $this->ResultVariable() : $this->SingleValuedPathExpression();
+
+        $item = new AST\OrderByItem($expr);
+
+        switch (true) {
+            case ($this->_lexer->isNextToken(Lexer::T_DESC)):
+                $this->match(Lexer::T_DESC);
+                $type = 'DESC';
+                break;
+
+            case ($this->_lexer->isNextToken(Lexer::T_ASC)):
+                $this->match(Lexer::T_ASC);
+                break;
+
+            default:
+                // Do nothing
+        }
+
+        $item->type = $type;
+
+        return $item;
+    }
+
+    /**
+     * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
+     *      EnumPrimary | SimpleEntityExpression | "NULL"
+     *
+     * NOTE: Since it is not possible to correctly recognize individual types, here is the full
+     * grammar that needs to be supported:
+     *
+     * NewValue ::= SimpleArithmeticExpression | "NULL"
+     *
+     * SimpleArithmeticExpression covers all *Primary grammar rules and also SimplEntityExpression
+     */
+    public function NewValue()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_NULL)) {
+            $this->match(Lexer::T_NULL);
+
+            return null;
+        }
+
+        if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
+            $this->match(Lexer::T_INPUT_PARAMETER);
+
+            return new AST\InputParameter($this->_lexer->token['value']);
+        }
+
+        return $this->SimpleArithmeticExpression();
+    }
+
+    /**
+     * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
+     *
+     * @return \Doctrine\ORM\Query\AST\IdentificationVariableDeclaration
+     */
+    public function IdentificationVariableDeclaration()
+    {
+        $rangeVariableDeclaration = $this->RangeVariableDeclaration();
+        $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ? $this->IndexBy() : null;
+        $joinVariableDeclarations = array();
+
+        while (
+            $this->_lexer->isNextToken(Lexer::T_LEFT) ||
+            $this->_lexer->isNextToken(Lexer::T_INNER) ||
+            $this->_lexer->isNextToken(Lexer::T_JOIN)
+        ) {
+            $joinVariableDeclarations[] = $this->JoinVariableDeclaration();
+        }
+
+        return new AST\IdentificationVariableDeclaration(
+            $rangeVariableDeclaration, $indexBy, $joinVariableDeclarations
+        );
+    }
+
+    /**
+     * SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable)
+     *
+     * @return \Doctrine\ORM\Query\AST\SubselectIdentificationVariableDeclaration |
+     *         \Doctrine\ORM\Query\AST\IdentificationVariableDeclaration
+     */
+    public function SubselectIdentificationVariableDeclaration()
+    {
+        $glimpse = $this->_lexer->glimpse();
+
+        /* NOT YET IMPLEMENTED!
+
+        if ($glimpse['type'] == Lexer::T_DOT) {
+            $subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration();
+            $subselectIdVarDecl->associationPathExpression = $this->AssociationPathExpression();
+            $this->match(Lexer::T_AS);
+            $subselectIdVarDecl->aliasIdentificationVariable = $this->AliasIdentificationVariable();
+
+            return $subselectIdVarDecl;
+        }
+        */
+
+        return $this->IdentificationVariableDeclaration();
+    }
+
+    /**
+     * JoinVariableDeclaration ::= Join [IndexBy]
+     *
+     * @return \Doctrine\ORM\Query\AST\JoinVariableDeclaration
+     */
+    public function JoinVariableDeclaration()
+    {
+        $join    = $this->Join();
+        $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ? $this->IndexBy() : null;
+
+        return new AST\JoinVariableDeclaration($join, $indexBy);
+    }
+
+    /**
+     * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
+     *
+     * @return \Doctrine\ORM\Query\AST\RangeVariableDeclaration
+     */
+    public function RangeVariableDeclaration()
+    {
+        $abstractSchemaName = $this->AbstractSchemaName();
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        $token = $this->_lexer->lookahead;
+        $aliasIdentificationVariable = $this->AliasIdentificationVariable();
+        $classMetadata = $this->_em->getClassMetadata($abstractSchemaName);
+
+        // Building queryComponent
+        $queryComponent = array(
+            'metadata'     => $classMetadata,
+            'parent'       => null,
+            'relation'     => null,
+            'map'          => null,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $token
+        );
+
+        $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent;
+
+        return new AST\RangeVariableDeclaration($abstractSchemaName, $aliasIdentificationVariable);
+    }
+
+    /**
+     * PartialObjectExpression ::= "PARTIAL" IdentificationVariable "." PartialFieldSet
+     * PartialFieldSet ::= "{" SimpleStateField {"," SimpleStateField}* "}"
+     *
+     * @return array
+     */
+    public function PartialObjectExpression()
+    {
+        $this->match(Lexer::T_PARTIAL);
+
+        $partialFieldSet = array();
+
+        $identificationVariable = $this->IdentificationVariable();
+
+        $this->match(Lexer::T_DOT);
+        $this->match(Lexer::T_OPEN_CURLY_BRACE);
+        $this->match(Lexer::T_IDENTIFIER);
+
+        $partialFieldSet[] = $this->_lexer->token['value'];
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+            $this->match(Lexer::T_IDENTIFIER);
+
+            $partialFieldSet[] = $this->_lexer->token['value'];
+        }
+
+        $this->match(Lexer::T_CLOSE_CURLY_BRACE);
+
+        $partialObjectExpression = new AST\PartialObjectExpression($identificationVariable, $partialFieldSet);
+
+        // Defer PartialObjectExpression validation
+        $this->_deferredPartialObjectExpressions[] = array(
+            'expression'   => $partialObjectExpression,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $this->_lexer->token,
+        );
+
+        return $partialObjectExpression;
+    }
+
+    /**
+     * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
+     *          ["AS"] AliasIdentificationVariable ["WITH" ConditionalExpression]
+     *
+     * @return \Doctrine\ORM\Query\AST\Join
+     */
+    public function Join()
+    {
+        // Check Join type
+        $joinType = AST\Join::JOIN_TYPE_INNER;
+
+        switch (true) {
+            case ($this->_lexer->isNextToken(Lexer::T_LEFT)):
+                $this->match(Lexer::T_LEFT);
+
+                $joinType = AST\Join::JOIN_TYPE_LEFT;
+
+                // Possible LEFT OUTER join
+                if ($this->_lexer->isNextToken(Lexer::T_OUTER)) {
+                    $this->match(Lexer::T_OUTER);
+
+                    $joinType = AST\Join::JOIN_TYPE_LEFTOUTER;
+                }
+                break;
+
+            case ($this->_lexer->isNextToken(Lexer::T_INNER)):
+                $this->match(Lexer::T_INNER);
+                break;
+
+            default:
+                // Do nothing
+        }
+
+        $this->match(Lexer::T_JOIN);
+
+        $joinPathExpression = $this->JoinAssociationPathExpression();
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        $token = $this->_lexer->lookahead;
+        $aliasIdentificationVariable = $this->AliasIdentificationVariable();
+
+        // Verify that the association exists.
+        $parentClass = $this->_queryComponents[$joinPathExpression->identificationVariable]['metadata'];
+        $assocField  = $joinPathExpression->associationField;
+
+        if ( ! $parentClass->hasAssociation($assocField)) {
+            $this->semanticalError(
+                "Class " . $parentClass->name . " has no association named '$assocField'."
+            );
+        }
+
+        $targetClassName = $parentClass->associationMappings[$assocField]['targetEntity'];
+
+        // Building queryComponent
+        $joinQueryComponent = array(
+            'metadata'     => $this->_em->getClassMetadata($targetClassName),
+            'parent'       => $joinPathExpression->identificationVariable,
+            'relation'     => $parentClass->getAssociationMapping($assocField),
+            'map'          => null,
+            'nestingLevel' => $this->_nestingLevel,
+            'token'        => $token
+        );
+
+        $this->_queryComponents[$aliasIdentificationVariable] = $joinQueryComponent;
+
+        // Create AST node
+        $join = new AST\Join($joinType, $joinPathExpression, $aliasIdentificationVariable);
+
+        // Check for ad-hoc Join conditions
+        if ($this->_lexer->isNextToken(Lexer::T_WITH)) {
+            $this->match(Lexer::T_WITH);
+
+            $join->conditionalExpression = $this->ConditionalExpression();
+        }
+
+        return $join;
+    }
+
+    /**
+     * IndexBy ::= "INDEX" "BY" StateFieldPathExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\IndexBy
+     */
+    public function IndexBy()
+    {
+        $this->match(Lexer::T_INDEX);
+        $this->match(Lexer::T_BY);
+        $pathExpr = $this->StateFieldPathExpression();
+
+        // Add the INDEX BY info to the query component
+        $this->_queryComponents[$pathExpr->identificationVariable]['map'] = $pathExpr->field;
+
+        return new AST\IndexBy($pathExpr);
+    }
+
+    /**
+     * ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary |
+     *                      StateFieldPathExpression | BooleanPrimary | CaseExpression |
+     *                      InstanceOfExpression
+     *
+     * @return mixed One of the possible expressions or subexpressions.
+     */
+    public function ScalarExpression()
+    {
+        $lookahead = $this->_lexer->lookahead['type'];
+
+        switch ($lookahead) {
+            case Lexer::T_IDENTIFIER:
+                $this->_lexer->peek(); // lookahead => '.'
+                $this->_lexer->peek(); // lookahead => token after '.'
+                $peek = $this->_lexer->peek(); // lookahead => token after the token after the '.'
+                $this->_lexer->resetPeek();
+
+                if ($this->_isMathOperator($peek)) {
+                    return $this->SimpleArithmeticExpression();
+                }
+
+                return $this->StateFieldPathExpression();
+
+            case Lexer::T_INTEGER:
+            case Lexer::T_FLOAT:
+                return $this->SimpleArithmeticExpression();
+
+            case Lexer::T_STRING:
+                return $this->StringPrimary();
+
+            case Lexer::T_TRUE:
+            case Lexer::T_FALSE:
+                $this->match($lookahead);
+
+                return new AST\Literal(AST\Literal::BOOLEAN, $this->_lexer->token['value']);
+
+            case Lexer::T_INPUT_PARAMETER:
+                return $this->inputsParameter();
+
+            case Lexer::T_CASE:
+            case Lexer::T_COALESCE:
+            case Lexer::T_NULLIF:
+                // Since NULLIF and COALESCE can be identified as a function,
+                // we need to check if before check for FunctionDeclaration
+                return $this->CaseExpression();
+
+            default:
+                if ( ! ($this->_isFunction() || $this->_isAggregateFunction($lookahead))) {
+                    $this->syntaxError();
+                }
+
+                // We may be in an ArithmeticExpression (find the matching ")" and inspect for Math operator)
+                $this->_lexer->peek(); // "("
+                $peek = $this->_peekBeyondClosingParenthesis();
+
+                if ($this->_isMathOperator($peek)) {
+                    return $this->SimpleArithmeticExpression();
+                }
+
+                if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
+                    return $this->AggregateExpression();
+                }
+
+                return $this->FunctionDeclaration();
+        }
+    }
+
+    /**
+     * CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression
+     * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+     * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+     * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+     * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
+     * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+     * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
+     * NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
+     *
+     * @return mixed One of the possible expressions or subexpressions.
+     */
+    public function CaseExpression()
+    {
+        $lookahead = $this->_lexer->lookahead['type'];
+
+        switch ($lookahead) {
+            case Lexer::T_NULLIF:
+                return $this->NullIfExpression();
+
+            case Lexer::T_COALESCE:
+                return $this->CoalesceExpression();
+
+            case Lexer::T_CASE:
+                $this->_lexer->resetPeek();
+                $peek = $this->_lexer->peek();
+
+                if ($peek['type'] === Lexer::T_WHEN) {
+                    return $this->GeneralCaseExpression();
+                }
+
+                return $this->SimpleCaseExpression();
+
+            default:
+                // Do nothing
+                break;
+        }
+
+        $this->syntaxError();
+    }
+
+    /**
+     * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\CoalesceExpression
+     */
+    public function CoalesceExpression()
+    {
+        $this->match(Lexer::T_COALESCE);
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        // Process ScalarExpressions (1..N)
+        $scalarExpressions = array();
+        $scalarExpressions[] = $this->ScalarExpression();
+
+        while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+            $this->match(Lexer::T_COMMA);
+
+            $scalarExpressions[] = $this->ScalarExpression();
+        }
+
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return new AST\CoalesceExpression($scalarExpressions);
+    }
+
+    /**
+     * NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\NullIfExpression
+     */
+    public function NullIfExpression()
+    {
+        $this->match(Lexer::T_NULLIF);
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $firstExpression = $this->ScalarExpression();
+        $this->match(Lexer::T_COMMA);
+        $secondExpression = $this->ScalarExpression();
+
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return new AST\NullIfExpression($firstExpression, $secondExpression);
+    }
+
+    /**
+     * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+     *
+     * @return \Doctrine\ORM\Query\AST\GeneralExpression
+     */
+    public function GeneralCaseExpression()
+    {
+        $this->match(Lexer::T_CASE);
+
+        // Process WhenClause (1..N)
+        $whenClauses = array();
+
+        do {
+            $whenClauses[] = $this->WhenClause();
+        } while ($this->_lexer->isNextToken(Lexer::T_WHEN));
+
+        $this->match(Lexer::T_ELSE);
+        $scalarExpression = $this->ScalarExpression();
+        $this->match(Lexer::T_END);
+
+        return new AST\GeneralCaseExpression($whenClauses, $scalarExpression);
+    }
+
+    /**
+     * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+     * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
+     */
+    public function SimpleCaseExpression()
+    {
+        $this->match(Lexer::T_CASE);
+        $caseOperand = $this->StateFieldPathExpression();
+
+        // Process SimpleWhenClause (1..N)
+        $simpleWhenClauses = array();
+
+        do {
+            $simpleWhenClauses[] = $this->SimpleWhenClause();
+        } while ($this->_lexer->isNextToken(Lexer::T_WHEN));
+
+        $this->match(Lexer::T_ELSE);
+        $scalarExpression = $this->ScalarExpression();
+        $this->match(Lexer::T_END);
+
+        return new AST\SimpleCaseExpression($caseOperand, $simpleWhenClauses, $scalarExpression);
+    }
+
+    /**
+     * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\WhenExpression
+     */
+    public function WhenClause()
+    {
+        $this->match(Lexer::T_WHEN);
+        $conditionalExpression = $this->ConditionalExpression();
+        $this->match(Lexer::T_THEN);
+
+        return new AST\WhenClause($conditionalExpression, $this->ScalarExpression());
+    }
+
+    /**
+     * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\SimpleWhenExpression
+     */
+    public function SimpleWhenClause()
+    {
+        $this->match(Lexer::T_WHEN);
+        $conditionalExpression = $this->ScalarExpression();
+        $this->match(Lexer::T_THEN);
+
+        return new AST\SimpleWhenClause($conditionalExpression, $this->ScalarExpression());
+    }
+
+    /**
+     * SelectExpression ::= (
+     *     IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration |
+     *     PartialObjectExpression | "(" Subselect ")" | CaseExpression
+     * ) [["AS"] ["HIDDEN"] AliasResultVariable]
+     *
+     * @return \Doctrine\ORM\Query\AST\SelectExpression
+     */
+    public function SelectExpression()
+    {
+        $expression    = null;
+        $identVariable = null;
+        $peek          = $this->_lexer->glimpse();
+        $lookaheadType = $this->_lexer->lookahead['type'];
+
+        switch (true) {
+            // ScalarExpression (u.name)
+            case ($lookaheadType === Lexer::T_IDENTIFIER && $peek['type'] === Lexer::T_DOT):
+                $expression = $this->ScalarExpression();
+                break;
+
+            // IdentificationVariable (u)
+            case ($lookaheadType === Lexer::T_IDENTIFIER && $peek['type'] !== Lexer::T_OPEN_PARENTHESIS):
+                $expression = $identVariable = $this->IdentificationVariable();
+                break;
+
+            // CaseExpression (CASE ... or NULLIF(...) or COALESCE(...))
+            case ($lookaheadType === Lexer::T_CASE):
+            case ($lookaheadType === Lexer::T_COALESCE):
+            case ($lookaheadType === Lexer::T_NULLIF):
+                $expression = $this->CaseExpression();
+                break;
+
+            // DQL Function (SUM(u.value) or SUM(u.value) + 1)
+            case ($this->_isFunction()):
+                $this->_lexer->peek(); // "("
+
+                switch (true) {
+                    case ($this->_isMathOperator($this->_peekBeyondClosingParenthesis())):
+                        // SUM(u.id) + COUNT(u.id)
+                        $expression = $this->ScalarExpression();
+                        break;
+
+                    case ($this->_isAggregateFunction($lookaheadType)):
+                        // COUNT(u.id)
+                        $expression = $this->AggregateExpression();
+                        break;
+
+                    default:
+                        // IDENTITY(u)
+                        $expression = $this->FunctionDeclaration();
+                        break;
+                }
+
+                break;
+
+            // PartialObjectExpression (PARTIAL u.{id, name})
+            case ($lookaheadType === Lexer::T_PARTIAL):
+                $expression    = $this->PartialObjectExpression();
+                $identVariable = $expression->identificationVariable;
+                break;
+
+            // Subselect
+            case ($lookaheadType === Lexer::T_OPEN_PARENTHESIS && $peek['type'] === Lexer::T_SELECT):
+                $this->match(Lexer::T_OPEN_PARENTHESIS);
+                $expression = $this->Subselect();
+                $this->match(Lexer::T_CLOSE_PARENTHESIS);
+                break;
+
+            // Shortcut: ScalarExpression => SimpleArithmeticExpression
+            case ($lookaheadType === Lexer::T_OPEN_PARENTHESIS):
+            case ($lookaheadType === Lexer::T_INTEGER):
+            case ($lookaheadType === Lexer::T_STRING):
+            case ($lookaheadType === Lexer::T_FLOAT):
+            // SimpleArithmeticExpression : (- u.value ) or ( + u.value )
+            case ($lookaheadType === Lexer::T_MINUS):
+            case ($lookaheadType === Lexer::T_PLUS):
+                $expression = $this->SimpleArithmeticExpression();
+                break;
+
+            default:
+                $this->syntaxError(
+                    'IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression',
+                    $this->_lexer->lookahead
+                );
+        }
+
+        // [["AS"] ["HIDDEN"] AliasResultVariable]
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        $hiddenAliasResultVariable = false;
+
+        if ($this->_lexer->isNextToken(Lexer::T_HIDDEN)) {
+            $this->match(Lexer::T_HIDDEN);
+
+            $hiddenAliasResultVariable = true;
+        }
+
+        $aliasResultVariable = null;
+
+        if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) {
+            $token = $this->_lexer->lookahead;
+            $aliasResultVariable = $this->AliasResultVariable();
+
+            // Include AliasResultVariable in query components.
+            $this->_queryComponents[$aliasResultVariable] = array(
+                'resultVariable' => $expression,
+                'nestingLevel'   => $this->_nestingLevel,
+                'token'          => $token,
+            );
+        }
+
+        // AST
+
+        $expr = new AST\SelectExpression($expression, $aliasResultVariable, $hiddenAliasResultVariable);
+
+        if ($identVariable) {
+            $this->_identVariableExpressions[$identVariable] = $expr;
+        }
+
+        return $expr;
+    }
+
+    /**
+     * SimpleSelectExpression ::=
+     *      StateFieldPathExpression | IdentificationVariable |
+     *      ((AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable])
+     *
+     * @return \Doctrine\ORM\Query\AST\SimpleSelectExpression
+     */
+    public function SimpleSelectExpression()
+    {
+        $peek = $this->_lexer->glimpse();
+
+        switch ($this->_lexer->lookahead['type']) {
+            case Lexer::T_IDENTIFIER:
+                switch (true) {
+                    case ($peek['type'] === Lexer::T_DOT):
+                        $expression = $this->StateFieldPathExpression();
+
+                        return new AST\SimpleSelectExpression($expression);
+
+                    case ($peek['type'] !== Lexer::T_OPEN_PARENTHESIS):
+                        $expression = $this->IdentificationVariable();
+
+                        return new AST\SimpleSelectExpression($expression);
+
+                    default:
+                        // Do nothing
+                }
+                break;
+
+            case Lexer::T_OPEN_PARENTHESIS:
+                if ($peek['type'] !== Lexer::T_SELECT) {
+                    // Shortcut: ScalarExpression => SimpleArithmeticExpression
+                    $expression = $this->SimpleArithmeticExpression();
+
+                    return new AST\SimpleSelectExpression($expression);
+                }
+
+                // Subselect
+                $this->match(Lexer::T_OPEN_PARENTHESIS);
+                $expression = $this->Subselect();
+                $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+                return new AST\SimpleSelectExpression($expression);
+
+            default:
+                // Do nothing
+        }
+
+        $this->_lexer->peek();
+
+        $expression = $this->ScalarExpression();
+        $expr       = new AST\SimpleSelectExpression($expression);
+
+        if ($this->_lexer->isNextToken(Lexer::T_AS)) {
+            $this->match(Lexer::T_AS);
+        }
+
+        if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) {
+            $token = $this->_lexer->lookahead;
+            $resultVariable = $this->AliasResultVariable();
+            $expr->fieldIdentificationVariable = $resultVariable;
+
+            // Include AliasResultVariable in query components.
+            $this->_queryComponents[$resultVariable] = array(
+                'resultvariable' => $expr,
+                'nestingLevel'   => $this->_nestingLevel,
+                'token'          => $token,
+            );
+        }
+
+        return $expr;
+    }
+
+    /**
+     * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
+     *
+     * @return \Doctrine\ORM\Query\AST\ConditionalExpression
+     */
+    public function ConditionalExpression()
+    {
+        $conditionalTerms = array();
+        $conditionalTerms[] = $this->ConditionalTerm();
+
+        while ($this->_lexer->isNextToken(Lexer::T_OR)) {
+            $this->match(Lexer::T_OR);
+
+            $conditionalTerms[] = $this->ConditionalTerm();
+        }
+
+        // Phase 1 AST optimization: Prevent AST\ConditionalExpression
+        // if only one AST\ConditionalTerm is defined
+        if (count($conditionalTerms) == 1) {
+            return $conditionalTerms[0];
+        }
+
+        return new AST\ConditionalExpression($conditionalTerms);
+    }
+
+    /**
+     * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
+     *
+     * @return \Doctrine\ORM\Query\AST\ConditionalTerm
+     */
+    public function ConditionalTerm()
+    {
+        $conditionalFactors = array();
+        $conditionalFactors[] = $this->ConditionalFactor();
+
+        while ($this->_lexer->isNextToken(Lexer::T_AND)) {
+            $this->match(Lexer::T_AND);
+
+            $conditionalFactors[] = $this->ConditionalFactor();
+        }
+
+        // Phase 1 AST optimization: Prevent AST\ConditionalTerm
+        // if only one AST\ConditionalFactor is defined
+        if (count($conditionalFactors) == 1) {
+            return $conditionalFactors[0];
+        }
+
+        return new AST\ConditionalTerm($conditionalFactors);
+    }
+
+    /**
+     * ConditionalFactor ::= ["NOT"] ConditionalPrimary
+     *
+     * @return \Doctrine\ORM\Query\AST\ConditionalFactor
+     */
+    public function ConditionalFactor()
+    {
+        $not = false;
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+
+            $not = true;
+        }
+
+        $conditionalPrimary = $this->ConditionalPrimary();
+
+        // Phase 1 AST optimization: Prevent AST\ConditionalFactor
+        // if only one AST\ConditionalPrimary is defined
+        if ( ! $not) {
+            return $conditionalPrimary;
+        }
+
+        $conditionalFactor = new AST\ConditionalFactor($conditionalPrimary);
+        $conditionalFactor->not = $not;
+
+        return $conditionalFactor;
+    }
+
+    /**
+     * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\ConditionalPrimary
+     */
+    public function ConditionalPrimary()
+    {
+        $condPrimary = new AST\ConditionalPrimary;
+
+        if ( ! $this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
+            $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression();
+
+            return $condPrimary;
+        }
+
+        // Peek beyond the matching closing paranthesis ')'
+        $peek = $this->_peekBeyondClosingParenthesis();
+
+        if (in_array($peek['value'], array("=",  "<", "<=", "<>", ">", ">=", "!=")) ||
+            in_array($peek['type'], array(Lexer::T_NOT, Lexer::T_BETWEEN, Lexer::T_LIKE, Lexer::T_IN, Lexer::T_IS, Lexer::T_EXISTS)) ||
+            $this->_isMathOperator($peek)) {
+            $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression();
+
+            return $condPrimary;
+        }
+
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+        $condPrimary->conditionalExpression = $this->ConditionalExpression();
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return $condPrimary;
+    }
+
+    /**
+     * SimpleConditionalExpression ::=
+     *      ComparisonExpression | BetweenExpression | LikeExpression |
+     *      InExpression | NullComparisonExpression | ExistsExpression |
+     *      EmptyCollectionComparisonExpression | CollectionMemberExpression |
+     *      InstanceOfExpression
+     */
+    public function SimpleConditionalExpression()
+    {
+        $token = $this->_lexer->lookahead;
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $token = $this->_lexer->glimpse();
+        }
+
+        if ($token['type'] === Lexer::T_EXISTS) {
+            return $this->ExistsExpression();
+        }
+
+        $peek = $this->_lexer->glimpse();
+
+        if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) {
+            if ($peek['value'] == '(') {
+                // Peek beyond the matching closing paranthesis ')'
+                $this->_lexer->peek();
+                $token = $this->_peekBeyondClosingParenthesis();
+            } else {
+                // Peek beyond the PathExpression (or InputParameter)
+                $peek = $this->_lexer->peek();
+
+                while ($peek['value'] === '.') {
+                    $this->_lexer->peek();
+                    $peek = $this->_lexer->peek();
+                }
+
+                // Also peek beyond a NOT if there is one
+                if ($peek['type'] === Lexer::T_NOT) {
+                    $peek = $this->_lexer->peek();
+                }
+
+                $token = $peek;
+
+                // We need to go even further in case of IS (differenciate between NULL and EMPTY)
+                $lookahead = $this->_lexer->peek();
+
+                // Also peek beyond a NOT if there is one
+                if ($lookahead['type'] === Lexer::T_NOT) {
+                    $lookahead = $this->_lexer->peek();
+                }
+
+                $this->_lexer->resetPeek();
+            }
+        }
+
+        switch ($token['type']) {
+            case Lexer::T_BETWEEN:
+                return $this->BetweenExpression();
+            case Lexer::T_LIKE:
+                return $this->LikeExpression();
+            case Lexer::T_IN:
+                return $this->InExpression();
+            case Lexer::T_INSTANCE:
+                return $this->InstanceOfExpression();
+            case Lexer::T_IS:
+                if ($lookahead['type'] == Lexer::T_NULL) {
+                    return $this->NullComparisonExpression();
+                }
+                return $this->EmptyCollectionComparisonExpression();
+            case Lexer::T_MEMBER:
+                return $this->CollectionMemberExpression();
+            default:
+                return $this->ComparisonExpression();
+        }
+    }
+
+    /**
+     * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
+     *
+     * @return \Doctrine\ORM\Query\AST\EmptyCollectionComparisonExpression
+     */
+    public function EmptyCollectionComparisonExpression()
+    {
+        $emptyColletionCompExpr = new AST\EmptyCollectionComparisonExpression(
+            $this->CollectionValuedPathExpression()
+        );
+        $this->match(Lexer::T_IS);
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $emptyColletionCompExpr->not = true;
+        }
+
+        $this->match(Lexer::T_EMPTY);
+
+        return $emptyColletionCompExpr;
+    }
+
+    /**
+     * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
+     *
+     * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
+     * SimpleEntityExpression ::= IdentificationVariable | InputParameter
+     *
+     * @return \Doctrine\ORM\Query\AST\CollectionMemberExpression
+     */
+    public function CollectionMemberExpression()
+    {
+        $not        = false;
+        $entityExpr = $this->EntityExpression();
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+
+            $not = true;
+        }
+
+        $this->match(Lexer::T_MEMBER);
+
+        if ($this->_lexer->isNextToken(Lexer::T_OF)) {
+            $this->match(Lexer::T_OF);
+        }
+
+        $collMemberExpr = new AST\CollectionMemberExpression(
+            $entityExpr, $this->CollectionValuedPathExpression()
+        );
+        $collMemberExpr->not = $not;
+
+        return $collMemberExpr;
+    }
+
+    /**
+     * Literal ::= string | char | integer | float | boolean
+     *
+     * @return string
+     */
+    public function Literal()
+    {
+        switch ($this->_lexer->lookahead['type']) {
+            case Lexer::T_STRING:
+                $this->match(Lexer::T_STRING);
+                return new AST\Literal(AST\Literal::STRING, $this->_lexer->token['value']);
+
+            case Lexer::T_INTEGER:
+            case Lexer::T_FLOAT:
+                $this->match(
+                    $this->_lexer->isNextToken(Lexer::T_INTEGER) ? Lexer::T_INTEGER : Lexer::T_FLOAT
+                );
+                return new AST\Literal(AST\Literal::NUMERIC, $this->_lexer->token['value']);
+
+            case Lexer::T_TRUE:
+            case Lexer::T_FALSE:
+                $this->match(
+                    $this->_lexer->isNextToken(Lexer::T_TRUE) ? Lexer::T_TRUE : Lexer::T_FALSE
+                );
+                return new AST\Literal(AST\Literal::BOOLEAN, $this->_lexer->token['value']);
+
+            default:
+                $this->syntaxError('Literal');
+        }
+    }
+
+    /**
+     * InParameter ::= Literal | InputParameter
+     *
+     * @return string | \Doctrine\ORM\Query\AST\InputParameter
+     */
+    public function InParameter()
+    {
+        if ($this->_lexer->lookahead['type'] == Lexer::T_INPUT_PARAMETER) {
+            return $this->inputsParameter();
+        }
+
+        return $this->Literal();
+    }
+
+    /**
+     * InputParameter ::= PositionalParameter | NamedParameter
+     *
+     * @return \Doctrine\ORM\Query\AST\InputParameter
+     */
+    public function InputParameter()
+    {
+        $this->match(Lexer::T_INPUT_PARAMETER);
+
+        return new AST\InputParameter($this->_lexer->token['value']);
+    }
+
+    /**
+     * ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\ArithmeticExpression
+     */
+    public function ArithmeticExpression()
+    {
+        $expr = new AST\ArithmeticExpression;
+
+        if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
+            $peek = $this->_lexer->glimpse();
+
+            if ($peek['type'] === Lexer::T_SELECT) {
+                $this->match(Lexer::T_OPEN_PARENTHESIS);
+                $expr->subselect = $this->Subselect();
+                $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+                return $expr;
+            }
+        }
+
+        $expr->simpleArithmeticExpression = $this->SimpleArithmeticExpression();
+
+        return $expr;
+    }
+
+    /**
+     * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
+     *
+     * @return \Doctrine\ORM\Query\AST\SimpleArithmeticExpression
+     */
+    public function SimpleArithmeticExpression()
+    {
+        $terms = array();
+        $terms[] = $this->ArithmeticTerm();
+
+        while (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) {
+            $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS);
+
+            $terms[] = $this->_lexer->token['value'];
+            $terms[] = $this->ArithmeticTerm();
+        }
+
+        // Phase 1 AST optimization: Prevent AST\SimpleArithmeticExpression
+        // if only one AST\ArithmeticTerm is defined
+        if (count($terms) == 1) {
+            return $terms[0];
+        }
+
+        return new AST\SimpleArithmeticExpression($terms);
+    }
+
+    /**
+     * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}*
+     *
+     * @return \Doctrine\ORM\Query\AST\ArithmeticTerm
+     */
+    public function ArithmeticTerm()
+    {
+        $factors = array();
+        $factors[] = $this->ArithmeticFactor();
+
+        while (($isMult = $this->_lexer->isNextToken(Lexer::T_MULTIPLY)) || $this->_lexer->isNextToken(Lexer::T_DIVIDE)) {
+            $this->match(($isMult) ? Lexer::T_MULTIPLY : Lexer::T_DIVIDE);
+
+            $factors[] = $this->_lexer->token['value'];
+            $factors[] = $this->ArithmeticFactor();
+        }
+
+        // Phase 1 AST optimization: Prevent AST\ArithmeticTerm
+        // if only one AST\ArithmeticFactor is defined
+        if (count($factors) == 1) {
+            return $factors[0];
+        }
+
+        return new AST\ArithmeticTerm($factors);
+    }
+
+    /**
+     * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary
+     *
+     * @return \Doctrine\ORM\Query\AST\ArithmeticFactor
+     */
+    public function ArithmeticFactor()
+    {
+        $sign = null;
+
+        if (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) {
+            $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS);
+            $sign = $isPlus;
+        }
+
+        $primary = $this->ArithmeticPrimary();
+
+        // Phase 1 AST optimization: Prevent AST\ArithmeticFactor
+        // if only one AST\ArithmeticPrimary is defined
+        if ($sign === null) {
+            return $primary;
+        }
+
+        return new AST\ArithmeticFactor($primary, $sign);
+    }
+
+    /**
+     * ArithmeticPrimary ::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")"
+     *          | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings
+     *          | FunctionsReturningDatetime | IdentificationVariable | ResultVariable | CaseExpression
+     */
+    public function ArithmeticPrimary()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
+            $this->match(Lexer::T_OPEN_PARENTHESIS);
+            $expr = $this->SimpleArithmeticExpression();
+
+            $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+            return $expr;
+        }
+
+        switch ($this->_lexer->lookahead['type']) {
+            case Lexer::T_COALESCE:
+            case Lexer::T_NULLIF:
+            case Lexer::T_CASE:
+                return $this->CaseExpression();
+
+            case Lexer::T_IDENTIFIER:
+                $peek = $this->_lexer->glimpse();
+
+                if ($peek['value'] == '(') {
+                    return $this->FunctionDeclaration();
+                }
+
+                if ($peek['value'] == '.') {
+                    return $this->SingleValuedPathExpression();
+                }
+
+                if (isset($this->_queryComponents[$this->_lexer->lookahead['value']]['resultVariable'])) {
+                    return $this->ResultVariable();
+                }
+
+                return $this->StateFieldPathExpression();
+
+            case Lexer::T_INPUT_PARAMETER:
+                return $this->inputsParameter();
+
+            default:
+                $peek = $this->_lexer->glimpse();
+
+                if ($peek['value'] == '(') {
+                    if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
+                        return $this->AggregateExpression();
+                    }
+
+                    return $this->FunctionDeclaration();
+                }
+
+                return $this->Literal();
+        }
+    }
+
+    /**
+     * StringExpression ::= StringPrimary | "(" Subselect ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\StringPrimary |
+     *         \Doctrine]ORM\Query\AST\Subselect
+     */
+    public function StringExpression()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
+            $peek = $this->_lexer->glimpse();
+
+            if ($peek['type'] === Lexer::T_SELECT) {
+                $this->match(Lexer::T_OPEN_PARENTHESIS);
+                $expr = $this->Subselect();
+                $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+                return $expr;
+            }
+        }
+
+        return $this->StringPrimary();
+    }
+
+    /**
+     * StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression
+     */
+    public function StringPrimary()
+    {
+        $lookaheadType = $this->_lexer->lookahead['type'];
+
+        switch ($lookaheadType) {
+            case Lexer::T_IDENTIFIER:
+                $peek = $this->_lexer->glimpse();
+
+                if ($peek['value'] == '.') {
+                    return $this->StateFieldPathExpression();
+                }
+
+                if ($peek['value'] == '(') {
+                    // do NOT directly go to FunctionsReturningString() because it doesnt check for custom functions.
+                    return $this->FunctionDeclaration();
+                }
+
+                $this->syntaxError("'.' or '('");
+                break;
+
+            case Lexer::T_STRING:
+                $this->match(Lexer::T_STRING);
+
+                return $this->_lexer->token['value'];
+
+            case Lexer::T_INPUT_PARAMETER:
+                return $this->inputsParameter();
+
+            case Lexer::T_CASE:
+            case Lexer::T_COALESCE:
+            case Lexer::T_NULLIF:
+                return $this->CaseExpression();
+
+            default:
+                if ($this->_isAggregateFunction($lookaheadType)) {
+                    return $this->AggregateExpression();
+                }
+        }
+
+        $this->syntaxError(
+            'StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression'
+        );
+    }
+
+    /**
+     * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\SingleValuedAssociationPathExpression |
+     *         \Doctrine\ORM\Query\AST\SimpleEntityExpression
+     */
+    public function EntityExpression()
+    {
+        $glimpse = $this->_lexer->glimpse();
+
+        if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER) && $glimpse['value'] === '.') {
+            return $this->SingleValuedAssociationPathExpression();
+        }
+
+        return $this->SimpleEntityExpression();
+    }
+
+    /**
+     * SimpleEntityExpression ::= IdentificationVariable | InputParameter
+     *
+     * @return string | \Doctrine\ORM\Query\AST\InputParameter
+     */
+    public function SimpleEntityExpression()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
+            return $this->inputsParameter();
+        }
+
+        return $this->StateFieldPathExpression();
+    }
+
+    /**
+     * AggregateExpression ::=
+     *  ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
+     *  "COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedPathExpression) ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\AggregateExpression
+     */
+    public function AggregateExpression()
+    {
+        $lookaheadType = $this->_lexer->lookahead['type'];
+        $isDistinct = false;
+
+        if ( ! in_array($lookaheadType, array(Lexer::T_COUNT, Lexer::T_AVG, Lexer::T_MAX, Lexer::T_MIN, Lexer::T_SUM))) {
+            $this->syntaxError('One of: MAX, MIN, AVG, SUM, COUNT');
+        }
+
+        $this->match($lookaheadType);
+        $functionName = $this->_lexer->token['value'];
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) {
+            $this->match(Lexer::T_DISTINCT);
+            $isDistinct = true;
+        }
+
+        $pathExp = ($lookaheadType === Lexer::T_COUNT)
+            ? $this->SingleValuedPathExpression()
+            : $this->SimpleArithmeticExpression();
+
+	    $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return new AST\AggregateExpression($functionName, $pathExp, $isDistinct);
+    }
+
+    /**
+     * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\QuantifiedExpression
+     */
+    public function QuantifiedExpression()
+    {
+        $lookaheadType = $this->_lexer->lookahead['type'];
+        $value = $this->_lexer->lookahead['value'];
+
+        if ( ! in_array($lookaheadType, array(Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME))) {
+            $this->syntaxError('ALL, ANY or SOME');
+        }
+
+        $this->match($lookaheadType);
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $qExpr = new AST\QuantifiedExpression($this->Subselect());
+        $qExpr->type = $value;
+
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return $qExpr;
+    }
+
+    /**
+     * BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
+     *
+     * @return \Doctrine\ORM\Query\AST\BetweenExpression
+     */
+    public function BetweenExpression()
+    {
+        $not = false;
+        $arithExpr1 = $this->ArithmeticExpression();
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $not = true;
+        }
+
+        $this->match(Lexer::T_BETWEEN);
+        $arithExpr2 = $this->ArithmeticExpression();
+        $this->match(Lexer::T_AND);
+        $arithExpr3 = $this->ArithmeticExpression();
+
+        $betweenExpr = new AST\BetweenExpression($arithExpr1, $arithExpr2, $arithExpr3);
+        $betweenExpr->not = $not;
+
+        return $betweenExpr;
+    }
+
+    /**
+     * ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression )
+     *
+     * @return \Doctrine\ORM\Query\AST\ComparisonExpression
+     */
+    public function ComparisonExpression()
+    {
+        $peek = $this->_lexer->glimpse();
+
+        $leftExpr  = $this->ArithmeticExpression();
+        $operator  = $this->ComparisonOperator();
+        $rightExpr = ($this->_isNextAllAnySome())
+            ? $this->QuantifiedExpression()
+            : $this->ArithmeticExpression();
+
+        return new AST\ComparisonExpression($leftExpr, $operator, $rightExpr);
+    }
+
+    /**
+     * InExpression ::= SingleValuedPathExpression ["NOT"] "IN" "(" (InParameter {"," InParameter}* | Subselect) ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\InExpression
+     */
+    public function InExpression()
+    {
+        $inExpression = new AST\InExpression($this->ArithmeticExpression());
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $inExpression->not = true;
+        }
+
+        $this->match(Lexer::T_IN);
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        if ($this->_lexer->isNextToken(Lexer::T_SELECT)) {
+            $inExpression->subselect = $this->Subselect();
+        } else {
+            $literals = array();
+            $literals[] = $this->InParameter();
+
+            while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+                $this->match(Lexer::T_COMMA);
+                $literals[] = $this->InParameter();
+            }
+
+            $inExpression->literals = $literals;
+        }
+
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return $inExpression;
+    }
+
+    /**
+     * InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")")
+     *
+     * @return \Doctrine\ORM\Query\AST\InstanceOfExpression
+     */
+    public function InstanceOfExpression()
+    {
+        $instanceOfExpression = new AST\InstanceOfExpression($this->IdentificationVariable());
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $instanceOfExpression->not = true;
+        }
+
+        $this->match(Lexer::T_INSTANCE);
+        $this->match(Lexer::T_OF);
+
+        $exprValues = array();
+
+        if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
+            $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+            $exprValues[] = $this->InstanceOfParameter();
+
+            while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
+                $this->match(Lexer::T_COMMA);
+
+                $exprValues[] = $this->InstanceOfParameter();
+            }
+
+            $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+            $instanceOfExpression->value = $exprValues;
+
+            return $instanceOfExpression;
+        }
+
+        $exprValues[] = $this->InstanceOfParameter();
+
+        $instanceOfExpression->value = $exprValues;
+
+        return $instanceOfExpression;
+    }
+
+    /**
+     * InstanceOfParameter ::= AbstractSchemaName | InputParameter
+     *
+     * @return mixed
+     */
+    public function InstanceOfParameter()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
+            $this->match(Lexer::T_INPUT_PARAMETER);
+
+            return new AST\InputParameter($this->_lexer->token['value']);
+        }
+
+        return $this->AliasIdentificationVariable();
+    }
+
+    /**
+     * LikeExpression ::= StringExpression ["NOT"] "LIKE" (string | input_parameter) ["ESCAPE" char]
+     *
+     * @return \Doctrine\ORM\Query\AST\LikeExpression
+     */
+    public function LikeExpression()
+    {
+        $stringExpr = $this->StringExpression();
+        $not = false;
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $not = true;
+        }
+
+        $this->match(Lexer::T_LIKE);
+
+        if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
+            $this->match(Lexer::T_INPUT_PARAMETER);
+            $stringPattern = new AST\InputParameter($this->_lexer->token['value']);
+        } else {
+            $this->match(Lexer::T_STRING);
+            $stringPattern = $this->_lexer->token['value'];
+        }
+
+        $escapeChar = null;
+
+        if ($this->_lexer->lookahead['type'] === Lexer::T_ESCAPE) {
+            $this->match(Lexer::T_ESCAPE);
+            $this->match(Lexer::T_STRING);
+            $escapeChar = $this->_lexer->token['value'];
+        }
+
+        $likeExpr = new AST\LikeExpression($stringExpr, $stringPattern, $escapeChar);
+        $likeExpr->not = $not;
+
+        return $likeExpr;
+    }
+
+    /**
+     * NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
+     *
+     * @return \Doctrine\ORM\Query\AST\NullComparisonExpression
+     */
+    public function NullComparisonExpression()
+    {
+        if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
+            $this->match(Lexer::T_INPUT_PARAMETER);
+            $expr = new AST\InputParameter($this->_lexer->token['value']);
+        } else {
+            $expr = $this->SingleValuedPathExpression();
+        }
+
+        $nullCompExpr = new AST\NullComparisonExpression($expr);
+        $this->match(Lexer::T_IS);
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $nullCompExpr->not = true;
+        }
+
+        $this->match(Lexer::T_NULL);
+
+        return $nullCompExpr;
+    }
+
+    /**
+     * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")"
+     *
+     * @return \Doctrine\ORM\Query\AST\ExistsExpression
+     */
+    public function ExistsExpression()
+    {
+        $not = false;
+
+        if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
+            $this->match(Lexer::T_NOT);
+            $not = true;
+        }
+
+        $this->match(Lexer::T_EXISTS);
+        $this->match(Lexer::T_OPEN_PARENTHESIS);
+
+        $existsExpression = new AST\ExistsExpression($this->Subselect());
+        $existsExpression->not = $not;
+
+        $this->match(Lexer::T_CLOSE_PARENTHESIS);
+
+        return $existsExpression;
+    }
+
+    /**
+     * ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!="
+     *
+     * @return string
+     */
+    public function ComparisonOperator()
+    {
+        switch ($this->_lexer->lookahead['value']) {
+            case '=':
+                $this->match(Lexer::T_EQUALS);
+
+                return '=';
+
+            case '<':
+                $this->match(Lexer::T_LOWER_THAN);
+                $operator = '<';
+
+                if ($this->_lexer->isNextToken(Lexer::T_EQUALS)) {
+                    $this->match(Lexer::T_EQUALS);
+                    $operator .= '=';
+                } else if ($this->_lexer->isNextToken(Lexer::T_GREATER_THAN)) {
+                    $this->match(Lexer::T_GREATER_THAN);
+                    $operator .= '>';
+                }
+
+                return $operator;
+
+            case '>':
+                $this->match(Lexer::T_GREATER_THAN);
+                $operator = '>';
+
+                if ($this->_lexer->isNextToken(Lexer::T_EQUALS)) {
+                    $this->match(Lexer::T_EQUALS);
+                    $operator .= '=';
+                }
+
+                return $operator;
+
+            case '!':
+                $this->match(Lexer::T_NEGATE);
+                $this->match(Lexer::T_EQUALS);
+
+                return '<>';
+
+            default:
+                $this->syntaxError('=, <, <=, <>, >, >=, !=');
+        }
+    }
+
+    /**
+     * FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDatetime
+     */
+    public function FunctionDeclaration()
+    {
+        $token = $this->_lexer->lookahead;
+        $funcName = strtolower($token['value']);
+
+        // Check for built-in functions first!
+        switch (true) {
+            case (isset(self::$_STRING_FUNCTIONS[$funcName])):
+                return $this->FunctionsReturningStrings();
+
+            case (isset(self::$_NUMERIC_FUNCTIONS[$funcName])):
+                return $this->FunctionsReturningNumerics();
+
+            case (isset(self::$_DATETIME_FUNCTIONS[$funcName])):
+                return $this->FunctionsReturningDatetime();
+
+            default:
+                return $this->CustomFunctionDeclaration();
+        }
+    }
+
+    /**
+     * Helper function for FunctionDeclaration grammar rule
+     */
+    private function CustomFunctionDeclaration()
+    {
+        $token = $this->_lexer->lookahead;
+        $funcName = strtolower($token['value']);
+
+        // Check for custom functions afterwards
+        $config = $this->_em->getConfiguration();
+
+        switch (true) {
+            case ($config->getCustomStringFunction($funcName) !== null):
+                return $this->CustomFunctionsReturningStrings();
+
+            case ($config->getCustomNumericFunction($funcName) !== null):
+                return $this->CustomFunctionsReturningNumerics();
+
+            case ($config->getCustomDatetimeFunction($funcName) !== null):
+                return $this->CustomFunctionsReturningDatetime();
+
+            default:
+                $this->syntaxError('known function', $token);
+        }
+    }
+
+    /**
+     * FunctionsReturningNumerics ::=
+     *      "LENGTH" "(" StringPrimary ")" |
+     *      "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" |
+     *      "ABS" "(" SimpleArithmeticExpression ")" |
+     *      "SQRT" "(" SimpleArithmeticExpression ")" |
+     *      "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
+     *      "SIZE" "(" CollectionValuedPathExpression ")"
+     */
+    public function FunctionsReturningNumerics()
+    {
+        $funcNameLower = strtolower($this->_lexer->lookahead['value']);
+        $funcClass     = self::$_NUMERIC_FUNCTIONS[$funcNameLower];
+
+        $function = new $funcClass($funcNameLower);
+        $function->parse($this);
+
+        return $function;
+    }
+
+    public function CustomFunctionsReturningNumerics()
+    {
+        // getCustomNumericFunction is case-insensitive
+        $funcName  = strtolower($this->_lexer->lookahead['value']);
+        $funcClass = $this->_em->getConfiguration()->getCustomNumericFunction($funcName);
+
+        $function = new $funcClass($funcName);
+        $function->parse($this);
+
+        return $function;
+    }
+
+    /**
+     * FunctionsReturningDateTime ::= "CURRENT_DATE" | "CURRENT_TIME" | "CURRENT_TIMESTAMP"
+     */
+    public function FunctionsReturningDatetime()
+    {
+        $funcNameLower = strtolower($this->_lexer->lookahead['value']);
+        $funcClass     = self::$_DATETIME_FUNCTIONS[$funcNameLower];
+
+        $function = new $funcClass($funcNameLower);
+        $function->parse($this);
+
+        return $function;
+    }
+
+    public function CustomFunctionsReturningDatetime()
+    {
+        // getCustomDatetimeFunction is case-insensitive
+        $funcName  = $this->_lexer->lookahead['value'];
+        $funcClass = $this->_em->getConfiguration()->getCustomDatetimeFunction($funcName);
+
+        $function = new $funcClass($funcName);
+        $function->parse($this);
+
+        return $function;
+    }
+
+    /**
+     * FunctionsReturningStrings ::=
+     *   "CONCAT" "(" StringPrimary "," StringPrimary ")" |
+     *   "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
+     *   "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" |
+     *   "LOWER" "(" StringPrimary ")" |
+     *   "UPPER" "(" StringPrimary ")"
+     */
+    public function FunctionsReturningStrings()
+    {
+        $funcNameLower = strtolower($this->_lexer->lookahead['value']);
+        $funcClass     = self::$_STRING_FUNCTIONS[$funcNameLower];
+
+        $function = new $funcClass($funcNameLower);
+        $function->parse($this);
+
+        return $function;
+    }
+
+    public function CustomFunctionsReturningStrings()
+    {
+        // getCustomStringFunction is case-insensitive
+        $funcName  = $this->_lexer->lookahead['value'];
+        $funcClass = $this->_em->getConfiguration()->getCustomStringFunction($funcName);
+
+        $function = new $funcClass($funcName);
+        $function->parse($this);
+
+        return $function;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParserResult.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParserResult.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ParserResult.php	(revision 345)
@@ -0,0 +1,141 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * Encapsulates the resulting components from a DQL query parsing process that
+ * can be serialized.
+ *
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Janne Vanhala <jpvanhal@cc.hut.fi>
+ * @author		Roman Borschel <roman@code-factory.org>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        http://www.doctrine-project.org
+ * @since       2.0
+ * @version     $Revision$
+ */
+class ParserResult
+{
+    /**
+     * The SQL executor used for executing the SQL.
+     *
+     * @var \Doctrine\ORM\Query\Exec\AbstractSqlExecutor
+     */
+    private $_sqlExecutor;
+
+    /**
+     * The ResultSetMapping that describes how to map the SQL result set.
+     *
+     * @var \Doctrine\ORM\Query\ResultSetMapping
+     */
+    private $_resultSetMapping;
+
+    /**
+     * The mappings of DQL parameter names/positions to SQL parameter positions.
+     *
+     * @var array
+     */
+    private $_parameterMappings = array();
+
+    /**
+     * Initializes a new instance of the <tt>ParserResult</tt> class.
+     * The new instance is initialized with an empty <tt>ResultSetMapping</tt>.
+     */
+    public function __construct()
+    {
+        $this->_resultSetMapping = new ResultSetMapping;
+    }
+
+    /**
+     * Gets the ResultSetMapping for the parsed query.
+     *
+     * @return ResultSetMapping The result set mapping of the parsed query or NULL
+     *                          if the query is not a SELECT query.
+     */
+    public function getResultSetMapping()
+    {
+        return $this->_resultSetMapping;
+    }
+
+    /**
+     * Sets the ResultSetMapping of the parsed query.
+     *
+     * @param ResultSetMapping $rsm
+     */
+    public function setResultSetMapping(ResultSetMapping $rsm)
+    {
+        $this->_resultSetMapping = $rsm;
+    }
+
+    /**
+     * Sets the SQL executor that should be used for this ParserResult.
+     *
+     * @param \Doctrine\ORM\Query\Exec\AbstractSqlExecutor $executor
+     */
+    public function setSqlExecutor($executor)
+    {
+        $this->_sqlExecutor = $executor;
+    }
+
+    /**
+     * Gets the SQL executor used by this ParserResult.
+     *
+     * @return \Doctrine\ORM\Query\Exec\AbstractSqlExecutor
+     */
+    public function getSqlExecutor()
+    {
+        return $this->_sqlExecutor;
+    }
+
+    /**
+     * Adds a DQL to SQL parameter mapping. One DQL parameter name/position can map to
+     * several SQL parameter positions.
+     *
+     * @param string|integer $dqlPosition
+     * @param integer $sqlPosition
+     */
+    public function addParameterMapping($dqlPosition, $sqlPosition)
+    {
+        $this->_parameterMappings[$dqlPosition][] = $sqlPosition;
+    }
+
+    /**
+     * Gets all DQL to SQL parameter mappings.
+     *
+     * @return array The parameter mappings.
+     */
+    public function getParameterMappings()
+    {
+        return $this->_parameterMappings;
+    }
+
+    /**
+     * Gets the SQL parameter positions for a DQL parameter name/position.
+     *
+     * @param string|integer $dqlPosition The name or position of the DQL parameter.
+     * @return array The positions of the corresponding SQL parameters.
+     */
+    public function getSqlParameterPositions($dqlPosition)
+    {
+        return $this->_parameterMappings[$dqlPosition];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Printer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Printer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/Printer.php	(revision 345)
@@ -0,0 +1,95 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * A parse tree printer for Doctrine Query Language parser.
+ *
+ * @author      Janne Vanhala <jpvanhal@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        http://www.phpdoctrine.org
+ * @since       2.0
+ * @version     $Revision$
+ */
+class Printer
+{
+    /**
+     * Current indentation level
+     *
+     * @var int
+     */
+    protected $_indent = 0;
+
+    /**
+     * Defines whether parse tree is printed (default, false) or not (true).
+     *
+     * @var bool
+     */
+    protected $_silent;
+
+    /**
+     * Constructs a new parse tree printer.
+     *
+     * @param bool $silent Parse tree will not be printed if true.
+     */
+    public function __construct($silent = false)
+    {
+        $this->_silent = $silent;
+    }
+
+    /**
+     * Prints an opening parenthesis followed by production name and increases
+     * indentation level by one.
+     *
+     * This method is called before executing a production.
+     *
+     * @param string $name production name
+     */
+    public function startProduction($name)
+    {
+        $this->println('(' . $name);
+        $this->_indent++;
+    }
+
+    /**
+     * Decreases indentation level by one and prints a closing parenthesis.
+     *
+     * This method is called after executing a production.
+     */
+    public function endProduction()
+    {
+        $this->_indent--;
+        $this->println(')');
+    }
+
+    /**
+     * Prints text indented with spaces depending on current indentation level.
+     *
+     * @param string $str text
+     */
+    public function println($str)
+    {
+        if ( ! $this->_silent) {
+            echo str_repeat('    ', $this->_indent), $str, "\n";
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/QueryException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/QueryException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/QueryException.php	(revision 345)
@@ -0,0 +1,154 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\ORM\Query\AST\PathExpression;
+
+/**
+ * Description of QueryException
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QueryException extends \Doctrine\ORM\ORMException
+{
+    public static function syntaxError($message)
+    {
+        return new self('[Syntax Error] ' . $message);
+    }
+
+    public static function semanticalError($message)
+    {
+        return new self('[Semantical Error] ' . $message);
+    }
+
+    public static function invalidLockMode()
+    {
+        return new self('Invalid lock mode hint provided.');
+    }
+
+    public static function invalidParameterType($expected, $received)
+    {
+        return new self('Invalid parameter type, ' . $received . ' given, but ' . $expected . ' expected.');
+    }
+
+    public static function invalidParameterPosition($pos)
+    {
+        return new self('Invalid parameter position: ' . $pos);
+    }
+
+    public static function invalidParameterNumber()
+    {
+        return new self("Invalid parameter number: number of bound variables does not match number of tokens");
+    }
+
+    public static function invalidParameterFormat($value)
+    {
+        return new self('Invalid parameter format, '.$value.' given, but :<name> or ?<num> expected.');
+    }
+
+    public static function unknownParameter($key)
+    {
+        return new self("Invalid parameter: token ".$key." is not defined in the query.");
+    }
+
+    public static function parameterTypeMissmatch()
+    {
+        return new self("DQL Query parameter and type numbers missmatch, but have to be exactly equal.");
+    }
+
+    public static function invalidPathExpression($pathExpr)
+    {
+        return new self(
+            "Invalid PathExpression '" . $pathExpr->identificationVariable . "." . $pathExpr->field . "'."
+        );
+    }
+
+    public static function invalidLiteral($literal) {
+        return new self("Invalid literal '$literal'");
+    }
+
+    /**
+     * @param array $assoc
+     */
+    public static function iterateWithFetchJoinCollectionNotAllowed($assoc)
+    {
+        return new self(
+            "Invalid query operation: Not allowed to iterate over fetch join collections ".
+            "in class ".$assoc['sourceEntity']." assocation ".$assoc['fieldName']
+        );
+    }
+
+    public static function partialObjectsAreDangerous()
+    {
+        return new self(
+            "Loading partial objects is dangerous. Fetch full objects or consider " .
+            "using a different fetch mode. If you really want partial objects, " .
+            "set the doctrine.forcePartialLoad query hint to TRUE."
+        );
+    }
+
+    public static function overwritingJoinConditionsNotYetSupported($assoc)
+    {
+        return new self(
+            "Unsupported query operation: It is not yet possible to overwrite the join ".
+            "conditions in class ".$assoc['sourceEntityName']." assocation ".$assoc['fieldName'].". ".
+            "Use WITH to append additional join conditions to the association."
+        );
+    }
+
+    public static function associationPathInverseSideNotSupported()
+    {
+        return new self(
+            "A single-valued association path expression to an inverse side is not supported".
+            " in DQL queries. Use an explicit join instead."
+        );
+    }
+
+    public static function iterateWithFetchJoinNotAllowed($assoc) {
+        return new self(
+            "Iterate with fetch join in class " . $assoc['sourceEntity'] .
+            " using association " . $assoc['fieldName'] . " not allowed."
+        );
+    }
+
+    public static function associationPathCompositeKeyNotSupported()
+    {
+        return new self(
+            "A single-valued association path expression to an entity with a composite primary ".
+            "key is not supported. Explicitly name the components of the composite primary key ".
+            "in the query."
+        );
+    }
+
+    public static function instanceOfUnrelatedClass($className, $rootClass)
+    {
+        return new self("Cannot check if a child of '" . $rootClass . "' is instanceof '" . $className . "', " .
+                "inheritance hierachy exists between these two classes.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMapping.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMapping.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMapping.php	(revision 345)
@@ -0,0 +1,485 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * A ResultSetMapping describes how a result set of an SQL query maps to a Doctrine result.
+ *
+ * IMPORTANT NOTE:
+ * The properties of this class are only public for fast internal READ access and to (drastically)
+ * reduce the size of serialized instances for more effective caching due to better (un-)serialization
+ * performance.
+ *
+ * <b>Users should use the public methods.</b>
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ * @todo Think about whether the number of lookup maps can be reduced.
+ */
+class ResultSetMapping
+{
+    /**
+     * @ignore
+     * @var boolean Whether the result is mixed (contains scalar values together with field values).
+     */
+    public $isMixed = false;
+
+    /**
+     * @ignore
+     * @var array Maps alias names to class names.
+     */
+    public $aliasMap = array();
+
+    /**
+     * @ignore
+     * @var array Maps alias names to related association field names.
+     */
+    public $relationMap = array();
+
+    /**
+     * @ignore
+     * @var array Maps alias names to parent alias names.
+     */
+    public $parentAliasMap = array();
+
+    /**
+     * @ignore
+     * @var array Maps column names in the result set to field names for each class.
+     */
+    public $fieldMappings = array();
+
+    /**
+     * @ignore
+     * @var array Maps column names in the result set to the alias/field name to use in the mapped result.
+     */
+    public $scalarMappings = array();
+
+    /**
+     * @ignore
+     * @var array Maps column names in the result set to the alias/field type to use in the mapped result.
+     */
+    public $typeMappings = array();
+
+    /**
+     * @ignore
+     * @var array Maps entities in the result set to the alias name to use in the mapped result.
+     */
+    public $entityMappings = array();
+
+    /**
+     * @ignore
+     * @var array Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names.
+     */
+    public $metaMappings = array();
+
+    /**
+     * @ignore
+     * @var array Maps column names in the result set to the alias they belong to.
+     */
+    public $columnOwnerMap = array();
+
+    /**
+     * @ignore
+     * @var array List of columns in the result set that are used as discriminator columns.
+     */
+    public $discriminatorColumns = array();
+
+    /**
+     * @ignore
+     * @var array Maps alias names to field names that should be used for indexing.
+     */
+    public $indexByMap = array();
+
+    /**
+     * @ignore
+     * @var array Map from column names to class names that declare the field the column is mapped to.
+     */
+    public $declaringClasses = array();
+
+    /**
+     * @var array This is necessary to hydrate derivate foreign keys correctly.
+     */
+    public $isIdentifierColumn = array();
+
+    /**
+     * Adds an entity result to this ResultSetMapping.
+     *
+     * @param string $class The class name of the entity.
+     * @param string $alias The alias for the class. The alias must be unique among all entity
+     *                      results or joined entity results within this ResultSetMapping.
+     * @param string $resultAlias The result alias with which the entity result should be
+     *                            placed in the result structure.
+     * @return ResultSetMapping This ResultSetMapping instance.
+     * @todo Rename: addRootEntity
+     */
+    public function addEntityResult($class, $alias, $resultAlias = null)
+    {
+        $this->aliasMap[$alias] = $class;
+        $this->entityMappings[$alias] = $resultAlias;
+
+        if ($resultAlias !== null) {
+            $this->isMixed = true;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets a discriminator column for an entity result or joined entity result.
+     * The discriminator column will be used to determine the concrete class name to
+     * instantiate.
+     *
+     * @param string $alias The alias of the entity result or joined entity result the discriminator
+     *                      column should be used for.
+     * @param string $discrColumn The name of the discriminator column in the SQL result set.
+     * @return ResultSetMapping This ResultSetMapping instance.
+     * @todo Rename: addDiscriminatorColumn
+     */
+    public function setDiscriminatorColumn($alias, $discrColumn)
+    {
+        $this->discriminatorColumns[$alias] = $discrColumn;
+        $this->columnOwnerMap[$discrColumn] = $alias;
+
+        return $this;
+    }
+
+    /**
+     * Sets a field to use for indexing an entity result or joined entity result.
+     *
+     * @param string $alias The alias of an entity result or joined entity result.
+     * @param string $fieldName The name of the field to use for indexing.
+     * @return ResultSetMapping This ResultSetMapping instance.
+     */
+    public function addIndexBy($alias, $fieldName)
+    {
+        $found = false;
+
+        foreach ($this->fieldMappings AS $columnName => $columnFieldName) {
+            if ( ! ($columnFieldName === $fieldName && $this->columnOwnerMap[$columnName] === $alias)) continue;
+
+            $this->addIndexByColumn($alias, $columnName);
+            $found = true;
+
+            break;
+        }
+
+        /* TODO: check if this exception can be put back, for now it's gone because of assumptions made by some ORM internals
+        if ( ! $found) {
+            $message = sprintf(
+                'Cannot add index by for DQL alias %s and field %s without calling addFieldResult() for them before.',
+                $alias,
+                $fieldName
+            );
+
+            throw new \LogicException($message);
+        }
+        */
+
+        return $this;
+    }
+
+    /**
+     * Set to index by a scalar result column name
+     *
+     * @param $resultColumnName
+     * @return ResultSetMapping This ResultSetMapping instance.
+     */
+    public function addIndexByScalar($resultColumnName)
+    {
+        $this->indexByMap['scalars'] = $resultColumnName;
+
+        return $this;
+    }
+
+    /**
+     * Sets a column to use for indexing an entity or joined entity result by the given alias name.
+     *
+     * @param $alias
+     * @param $resultColumnName
+     * @return ResultSetMapping This ResultSetMapping instance.
+     */
+    public function addIndexByColumn($alias, $resultColumnName)
+    {
+        $this->indexByMap[$alias] = $resultColumnName;
+
+        return $this;
+    }
+
+    /**
+     * Checks whether an entity result or joined entity result with a given alias has
+     * a field set for indexing.
+     *
+     * @param string $alias
+     * @return boolean
+     * @todo Rename: isIndexed($alias)
+     */
+    public function hasIndexBy($alias)
+    {
+        return isset($this->indexByMap[$alias]);
+    }
+
+    /**
+     * Checks whether the column with the given name is mapped as a field result
+     * as part of an entity result or joined entity result.
+     *
+     * @param string $columnName The name of the column in the SQL result set.
+     * @return boolean
+     * @todo Rename: isField
+     */
+    public function isFieldResult($columnName)
+    {
+        return isset($this->fieldMappings[$columnName]);
+    }
+
+    /**
+     * Adds a field to the result that belongs to an entity or joined entity.
+     *
+     * @param string $alias The alias of the root entity or joined entity to which the field belongs.
+     * @param string $columnName The name of the column in the SQL result set.
+     * @param string $fieldName The name of the field on the declaring class.
+     * @param string $declaringClass The name of the class that declares/owns the specified field.
+     *                               When $alias refers to a superclass in a mapped hierarchy but
+     *                               the field $fieldName is defined on a subclass, specify that here.
+     *                               If not specified, the field is assumed to belong to the class
+     *                               designated by $alias.
+     * @return ResultSetMapping This ResultSetMapping instance.
+     * @todo Rename: addField
+     */
+    public function addFieldResult($alias, $columnName, $fieldName, $declaringClass = null)
+    {
+        // column name (in result set) => field name
+        $this->fieldMappings[$columnName] = $fieldName;
+        // column name => alias of owner
+        $this->columnOwnerMap[$columnName] = $alias;
+        // field name => class name of declaring class
+        $this->declaringClasses[$columnName] = $declaringClass ?: $this->aliasMap[$alias];
+
+        if ( ! $this->isMixed && $this->scalarMappings) {
+            $this->isMixed = true;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds a joined entity result.
+     *
+     * @param string $class The class name of the joined entity.
+     * @param string $alias The unique alias to use for the joined entity.
+     * @param string $parentAlias The alias of the entity result that is the parent of this joined result.
+     * @param object $relation The association field that connects the parent entity result with the joined entity result.
+     * @return ResultSetMapping This ResultSetMapping instance.
+     * @todo Rename: addJoinedEntity
+     */
+    public function addJoinedEntityResult($class, $alias, $parentAlias, $relation)
+    {
+        $this->aliasMap[$alias]       = $class;
+        $this->parentAliasMap[$alias] = $parentAlias;
+        $this->relationMap[$alias]    = $relation;
+
+        return $this;
+    }
+
+    /**
+     * Adds a scalar result mapping.
+     *
+     * @param string $columnName The name of the column in the SQL result set.
+     * @param string $alias The result alias with which the scalar result should be placed in the result structure.
+     * @param string $type The column type
+     *
+     * @return ResultSetMapping This ResultSetMapping instance.
+     *
+     * @todo Rename: addScalar
+     */
+    public function addScalarResult($columnName, $alias, $type = null)
+    {
+        $this->scalarMappings[$columnName] = $alias;
+        $this->typeMappings[$columnName]   = $type ?: 'string';
+
+        if ( ! $this->isMixed && $this->fieldMappings) {
+            $this->isMixed = true;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Checks whether a column with a given name is mapped as a scalar result.
+     *
+     * @param string $columName The name of the column in the SQL result set.
+     * @return boolean
+     * @todo Rename: isScalar
+     */
+    public function isScalarResult($columnName)
+    {
+        return isset($this->scalarMappings[$columnName]);
+    }
+
+    /**
+     * Gets the name of the class of an entity result or joined entity result,
+     * identified by the given unique alias.
+     *
+     * @param string $alias
+     * @return string
+     */
+    public function getClassName($alias)
+    {
+        return $this->aliasMap[$alias];
+    }
+
+    /**
+     * Gets the field alias for a column that is mapped as a scalar value.
+     *
+     * @param string $columnName The name of the column in the SQL result set.
+     * @return string
+     */
+    public function getScalarAlias($columnName)
+    {
+        return $this->scalarMappings[$columnName];
+    }
+
+    /**
+     * Gets the name of the class that owns a field mapping for the specified column.
+     *
+     * @param string $columnName
+     * @return string
+     */
+    public function getDeclaringClass($columnName)
+    {
+        return $this->declaringClasses[$columnName];
+    }
+
+    /**
+     *
+     * @param string $alias
+     * @return AssociationMapping
+     */
+    public function getRelation($alias)
+    {
+        return $this->relationMap[$alias];
+    }
+
+    /**
+     *
+     * @param string $alias
+     * @return boolean
+     */
+    public function isRelation($alias)
+    {
+        return isset($this->relationMap[$alias]);
+    }
+
+    /**
+     * Gets the alias of the class that owns a field mapping for the specified column.
+     *
+     * @param string $columnName
+     * @return string
+     */
+    public function getEntityAlias($columnName)
+    {
+        return $this->columnOwnerMap[$columnName];
+    }
+
+    /**
+     * Gets the parent alias of the given alias.
+     *
+     * @param string $alias
+     * @return string
+     */
+    public function getParentAlias($alias)
+    {
+        return $this->parentAliasMap[$alias];
+    }
+
+    /**
+     * Checks whether the given alias has a parent alias.
+     *
+     * @param string $alias
+     * @return boolean
+     */
+    public function hasParentAlias($alias)
+    {
+        return isset($this->parentAliasMap[$alias]);
+    }
+
+    /**
+     * Gets the field name for a column name.
+     *
+     * @param string $columnName
+     * @return string
+     */
+    public function getFieldName($columnName)
+    {
+        return $this->fieldMappings[$columnName];
+    }
+
+    /**
+     *
+     * @return array
+     */
+    public function getAliasMap()
+    {
+        return $this->aliasMap;
+    }
+
+    /**
+     * Gets the number of different entities that appear in the mapped result.
+     *
+     * @return integer
+     */
+    public function getEntityResultCount()
+    {
+        return count($this->aliasMap);
+    }
+
+    /**
+     * Checks whether this ResultSetMapping defines a mixed result.
+     * Mixed results can only occur in object and array (graph) hydration. In such a
+     * case a mixed result means that scalar values are mixed with objects/array in
+     * the result.
+     *
+     * @return boolean
+     */
+    public function isMixedResult()
+    {
+        return $this->isMixed;
+    }
+
+    /**
+     * Adds a meta column (foreign key or discriminator column) to the result set.
+     *
+     * @param string $alias
+     * @param string $columnName
+     * @param string $fieldName
+     * @param bool
+     * @return ResultSetMapping This ResultSetMapping instance.
+     */
+    public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false)
+    {
+        $this->metaMappings[$columnName] = $fieldName;
+        $this->columnOwnerMap[$columnName] = $alias;
+
+        if ($isIdentifierColumn) {
+            $this->isIdentifierColumn[$alias][$columnName] = true;
+        }
+
+        return $this;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMappingBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMappingBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/ResultSetMappingBuilder.php	(revision 345)
@@ -0,0 +1,109 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * A ResultSetMappingBuilder uses the EntityManager to automatically populate entity fields
+ *
+ * @author Michael Ridgway <mcridgway@gmail.com>
+ * @since 2.1
+ */
+class ResultSetMappingBuilder extends ResultSetMapping
+{
+    /**
+     * @var EntityManager
+     */
+    private $em;
+
+    /**
+     * @param EntityManager
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Adds a root entity and all of its fields to the result set.
+     *
+     * @param string $class The class name of the root entity.
+     * @param string $alias The unique alias to use for the root entity.
+     * @param array $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName)
+     */
+    public function addRootEntityFromClassMetadata($class, $alias, $renamedColumns = array())
+    {
+        $this->addEntityResult($class, $alias);
+        $this->addAllClassFields($class, $alias, $renamedColumns);
+    }
+
+    /**
+     * Adds a joined entity and all of its fields to the result set.
+     *
+     * @param string $class The class name of the joined entity.
+     * @param string $alias The unique alias to use for the joined entity.
+     * @param string $parentAlias The alias of the entity result that is the parent of this joined result.
+     * @param object $relation The association field that connects the parent entity result with the joined entity result.
+     * @param array $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName)
+     */
+    public function addJoinedEntityFromClassMetadata($class, $alias, $parentAlias, $relation, $renamedColumns = array())
+    {
+        $this->addJoinedEntityResult($class, $alias, $parentAlias, $relation);
+        $this->addAllClassFields($class, $alias, $renamedColumns);
+    }
+
+    /**
+     * Adds all fields of the given class to the result set mapping (columns and meta fields)
+     */
+    protected function addAllClassFields($class, $alias, $renamedColumns = array())
+    {
+        $classMetadata = $this->em->getClassMetadata($class);
+        if ($classMetadata->isInheritanceTypeSingleTable() || $classMetadata->isInheritanceTypeJoined()) {
+            throw new \InvalidArgumentException('ResultSetMapping builder does not currently support inheritance.');
+        }
+        $platform = $this->em->getConnection()->getDatabasePlatform();
+        foreach ($classMetadata->getColumnNames() AS $columnName) {
+            $propertyName = $classMetadata->getFieldName($columnName);
+            if (isset($renamedColumns[$columnName])) {
+                $columnName = $renamedColumns[$columnName];
+            }
+            $columnName = $platform->getSQLResultCasing($columnName);
+            if (isset($this->fieldMappings[$columnName])) {
+                throw new \InvalidArgumentException("The column '$columnName' conflicts with another column in the mapper.");
+            }
+            $this->addFieldResult($alias, $columnName, $propertyName);
+        }
+        foreach ($classMetadata->associationMappings AS $associationMapping) {
+            if ($associationMapping['isOwningSide'] && $associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
+                foreach ($associationMapping['joinColumns'] AS $joinColumn) {
+                    $columnName = $joinColumn['name'];
+                    $renamedColumnName = isset($renamedColumns[$columnName]) ? $renamedColumns[$columnName] : $columnName;
+                    $renamedColumnName = $platform->getSQLResultCasing($renamedColumnName);
+                    if (isset($this->metaMappings[$renamedColumnName])) {
+                        throw new \InvalidArgumentException("The column '$renamedColumnName' conflicts with another column in the mapper.");
+                    }
+                    $this->addMetaResult($alias, $renamedColumnName, $columnName);
+                }
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/SqlWalker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/SqlWalker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/SqlWalker.php	(revision 345)
@@ -0,0 +1,2159 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+use Doctrine\DBAL\LockMode,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Query,
+    Doctrine\ORM\Query\QueryException,
+    Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * The SqlWalker is a TreeWalker that walks over a DQL AST and constructs
+ * the corresponding SQL.
+ *
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Alexander <iam.asm89@gmail.com>
+ * @since  2.0
+ * @todo Rename: SQLWalker
+ */
+class SqlWalker implements TreeWalker
+{
+    /**
+     * @var string
+     */
+    const HINT_DISTINCT = 'doctrine.distinct';
+  
+    /**
+     * @var ResultSetMapping
+     */
+    private $_rsm;
+
+    /** Counters for generating unique column aliases, table aliases and parameter indexes. */
+    private $_aliasCounter = 0;
+    private $_tableAliasCounter = 0;
+    private $_scalarResultCounter = 1;
+    private $_sqlParamIndex = 0;
+
+    /**
+     * @var ParserResult
+     */
+    private $_parserResult;
+
+    /**
+     * @var EntityManager
+     */
+    private $_em;
+
+    /**
+     * @var \Doctrine\DBAL\Connection
+     */
+    private $_conn;
+
+    /**
+     * @var AbstractQuery
+     */
+    private $_query;
+
+    private $_tableAliasMap = array();
+
+    /** Map from result variable names to their SQL column alias names. */
+    private $_scalarResultAliasMap = array();
+
+    /**
+     * Map from DQL-Alias + Field-Name to SQL Column Alias
+     *
+     * @var array
+     */
+    private $_scalarFields = array();
+
+    /** Map of all components/classes that appear in the DQL query. */
+    private $_queryComponents;
+
+    /** A list of classes that appear in non-scalar SelectExpressions. */
+    private $_selectedClasses = array();
+
+    /**
+     * The DQL alias of the root class of the currently traversed query.
+     */
+    private $_rootAliases = array();
+
+    /**
+     * Flag that indicates whether to generate SQL table aliases in the SQL.
+     * These should only be generated for SELECT queries, not for UPDATE/DELETE.
+     */
+    private $_useSqlTableAliases = true;
+
+    /**
+     * The database platform abstraction.
+     *
+     * @var AbstractPlatform
+     */
+    private $_platform;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($query, $parserResult, array $queryComponents)
+    {
+        $this->_query = $query;
+        $this->_parserResult = $parserResult;
+        $this->_queryComponents = $queryComponents;
+        $this->_rsm = $parserResult->getResultSetMapping();
+        $this->_em = $query->getEntityManager();
+        $this->_conn = $this->_em->getConnection();
+        $this->_platform = $this->_conn->getDatabasePlatform();
+    }
+
+    /**
+     * Gets the Query instance used by the walker.
+     *
+     * @return Query.
+     */
+    public function getQuery()
+    {
+        return $this->_query;
+    }
+
+    /**
+     * Gets the Connection used by the walker.
+     *
+     * @return Connection
+     */
+    public function getConnection()
+    {
+        return $this->_conn;
+    }
+
+    /**
+     * Gets the EntityManager used by the walker.
+     *
+     * @return EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * Gets the information about a single query component.
+     *
+     * @param string $dqlAlias The DQL alias.
+     * @return array
+     */
+    public function getQueryComponent($dqlAlias)
+    {
+        return $this->_queryComponents[$dqlAlias];
+    }
+
+    /**
+     * Gets an executor that can be used to execute the result of this walker.
+     *
+     * @return AbstractExecutor
+     */
+    public function getExecutor($AST)
+    {
+        switch (true) {
+            case ($AST instanceof AST\DeleteStatement):
+                $primaryClass = $this->_em->getClassMetadata($AST->deleteClause->abstractSchemaName);
+
+                return ($primaryClass->isInheritanceTypeJoined())
+                    ? new Exec\MultiTableDeleteExecutor($AST, $this)
+                    : new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
+
+            case ($AST instanceof AST\UpdateStatement):
+                $primaryClass = $this->_em->getClassMetadata($AST->updateClause->abstractSchemaName);
+
+                return ($primaryClass->isInheritanceTypeJoined())
+                    ? new Exec\MultiTableUpdateExecutor($AST, $this)
+                    : new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
+
+            default:
+                return new Exec\SingleSelectExecutor($AST, $this);
+        }
+    }
+
+    /**
+     * Generates a unique, short SQL table alias.
+     *
+     * @param string $tableName Table name
+     * @param string $dqlAlias The DQL alias.
+     * @return string Generated table alias.
+     */
+    public function getSQLTableAlias($tableName, $dqlAlias = '')
+    {
+        $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : '';
+
+        if ( ! isset($this->_tableAliasMap[$tableName])) {
+            $this->_tableAliasMap[$tableName] = strtolower(substr($tableName, 0, 1)) . $this->_tableAliasCounter++ . '_';
+        }
+
+        return $this->_tableAliasMap[$tableName];
+    }
+
+    /**
+     * Forces the SqlWalker to use a specific alias for a table name, rather than
+     * generating an alias on its own.
+     *
+     * @param string $tableName
+     * @param string $alias
+     * @param string $dqlAlias
+     * @return string
+     */
+    public function setSQLTableAlias($tableName, $alias, $dqlAlias = '')
+    {
+        $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : '';
+
+        $this->_tableAliasMap[$tableName] = $alias;
+
+        return $alias;
+    }
+
+    /**
+     * Gets an SQL column alias for a column name.
+     *
+     * @param string $columnName
+     * @return string
+     */
+    public function getSQLColumnAlias($columnName)
+    {
+        // Trim the column alias to the maximum identifier length of the platform.
+        // If the alias is to long, characters are cut off from the beginning.
+        return $this->_platform->getSQLResultCasing(
+            substr($columnName . $this->_aliasCounter++, -$this->_platform->getMaxIdentifierLength())
+        );
+    }
+
+    /**
+     * Generates the SQL JOINs that are necessary for Class Table Inheritance
+     * for the given class.
+     *
+     * @param ClassMetadata $class The class for which to generate the joins.
+     * @param string $dqlAlias The DQL alias of the class.
+     * @return string The SQL.
+     */
+    private function _generateClassTableInheritanceJoins($class, $dqlAlias)
+    {
+        $sql = '';
+
+        $baseTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+        // INNER JOIN parent class tables
+        foreach ($class->parentClasses as $parentClassName) {
+            $parentClass = $this->_em->getClassMetadata($parentClassName);
+            $tableAlias  = $this->getSQLTableAlias($parentClass->getTableName(), $dqlAlias);
+
+            // If this is a joined association we must use left joins to preserve the correct result.
+            $sql .= isset($this->_queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER ';
+            $sql .= 'JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+
+            $sqlParts = array();
+
+            foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
+                $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName;
+            }
+
+            // Add filters on the root class
+            if ($filterSql = $this->generateFilterConditionSQL($parentClass, $tableAlias)) {
+                $sqlParts[] = $filterSql;
+            }
+
+            $sql .= implode(' AND ', $sqlParts);
+        }
+
+        // Ignore subclassing inclusion if partial objects is disallowed
+        if ($this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
+            return $sql;
+        }
+
+        // LEFT JOIN child class tables
+        foreach ($class->subClasses as $subClassName) {
+            $subClass   = $this->_em->getClassMetadata($subClassName);
+            $tableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias);
+
+            $sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+
+            $sqlParts = array();
+
+            foreach ($subClass->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
+                $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName;
+            }
+
+            $sql .= implode(' AND ', $sqlParts);
+        }
+
+        return $sql;
+    }
+
+    private function _generateOrderedCollectionOrderByItems()
+    {
+        $sqlParts = array();
+
+        foreach ($this->_selectedClasses AS $selectedClass) {
+            $dqlAlias = $selectedClass['dqlAlias'];
+            $qComp    = $this->_queryComponents[$dqlAlias];
+
+            if ( ! isset($qComp['relation']['orderBy'])) continue;
+
+            foreach ($qComp['relation']['orderBy'] AS $fieldName => $orientation) {
+                $columnName = $qComp['metadata']->getQuotedColumnName($fieldName, $this->_platform);
+                $tableName  = ($qComp['metadata']->isInheritanceTypeJoined())
+                    ? $this->_em->getUnitOfWork()->getEntityPersister($qComp['metadata']->name)->getOwningTable($fieldName)
+                    : $qComp['metadata']->getTableName();
+
+                $sqlParts[] = $this->getSQLTableAlias($tableName, $dqlAlias) . '.' . $columnName . ' ' . $orientation;
+            }
+        }
+
+        return implode(', ', $sqlParts);
+    }
+
+    /**
+     * Generates a discriminator column SQL condition for the class with the given DQL alias.
+     *
+     * @param array $dqlAliases List of root DQL aliases to inspect for discriminator restrictions.
+     * @return string
+     */
+    private function _generateDiscriminatorColumnConditionSQL(array $dqlAliases)
+    {
+        $sqlParts = array();
+
+        foreach ($dqlAliases as $dqlAlias) {
+            $class = $this->_queryComponents[$dqlAlias]['metadata'];
+
+            if ( ! $class->isInheritanceTypeSingleTable()) continue;
+
+            $conn   = $this->_em->getConnection();
+            $values = array();
+
+            if ($class->discriminatorValue !== null) { // discrimnators can be 0
+                $values[] = $conn->quote($class->discriminatorValue);
+            }
+
+            foreach ($class->subClasses as $subclassName) {
+                $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue);
+            }
+
+            $sqlParts[] = (($this->_useSqlTableAliases) ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' : '')
+                        . $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
+        }
+
+        $sql = implode(' AND ', $sqlParts);
+
+        return (count($sqlParts) > 1) ? '(' . $sql . ')' : $sql;
+    }
+
+    /**
+     * Generates the filter SQL for a given entity and table alias.
+     *
+     * @param ClassMetadata $targetEntity Metadata of the target entity.
+     * @param string $targetTableAlias The table alias of the joined/selected table.
+     *
+     * @return string The SQL query part to add to a query.
+     */
+    private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
+    {
+        if (!$this->_em->hasFilters()) {
+            return '';
+        }
+
+        switch($targetEntity->inheritanceType) {
+            case ClassMetadata::INHERITANCE_TYPE_NONE:
+                break;
+            case ClassMetadata::INHERITANCE_TYPE_JOINED:
+                // The classes in the inheritance will be added to the query one by one,
+                // but only the root node is getting filtered
+                if ($targetEntity->name !== $targetEntity->rootEntityName) {
+                    return '';
+                }
+                break;
+            case ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE:
+                // With STI the table will only be queried once, make sure that the filters
+                // are added to the root entity
+                $targetEntity = $this->_em->getClassMetadata($targetEntity->rootEntityName);
+                break;
+            default:
+                //@todo: throw exception?
+                return '';
+            break;
+        }
+
+        $filterClauses = array();
+        foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) {
+            if ('' !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) {
+                $filterClauses[] = '(' . $filterExpr . ')';
+            }
+        }
+
+        return implode(' AND ', $filterClauses);
+    }
+    /**
+     * Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkSelectStatement(AST\SelectStatement $AST)
+    {
+        $sql  = $this->walkSelectClause($AST->selectClause);
+        $sql .= $this->walkFromClause($AST->fromClause);
+        $sql .= $this->walkWhereClause($AST->whereClause);
+        $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : '';
+        $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : '';
+
+        if (($orderByClause = $AST->orderByClause) !== null) {
+            $sql .= $AST->orderByClause ? $this->walkOrderByClause($AST->orderByClause) : '';
+        } else if (($orderBySql = $this->_generateOrderedCollectionOrderByItems()) !== '') {
+            $sql .= ' ORDER BY ' . $orderBySql;
+        }
+
+        $sql = $this->_platform->modifyLimitQuery(
+            $sql, $this->_query->getMaxResults(), $this->_query->getFirstResult()
+        );
+
+        if (($lockMode = $this->_query->getHint(Query::HINT_LOCK_MODE)) !== false) {
+            switch ($lockMode) {
+                case LockMode::PESSIMISTIC_READ:
+                    $sql .= ' ' . $this->_platform->getReadLockSQL();
+                    break;
+
+                case LockMode::PESSIMISTIC_WRITE:
+                    $sql .= ' ' . $this->_platform->getWriteLockSQL();
+                    break;
+
+                case LockMode::OPTIMISTIC:
+                    foreach ($this->_selectedClasses AS $selectedClass) {
+                        if ( ! $selectedClass['class']->isVersioned) {
+                            throw \Doctrine\ORM\OptimisticLockException::lockFailed($selectedClass['class']->name);
+                        }
+                    }
+                    break;
+                case LockMode::NONE:
+                    break;
+
+                default:
+                    throw \Doctrine\ORM\Query\QueryException::invalidLockMode();
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateStatement
+     * @return string The SQL.
+     */
+    public function walkUpdateStatement(AST\UpdateStatement $AST)
+    {
+        $this->_useSqlTableAliases = false;
+
+        return $this->walkUpdateClause($AST->updateClause)
+             . $this->walkWhereClause($AST->whereClause);
+    }
+
+    /**
+     * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteStatement
+     * @return string The SQL.
+     */
+    public function walkDeleteStatement(AST\DeleteStatement $AST)
+    {
+        $this->_useSqlTableAliases = false;
+
+        return $this->walkDeleteClause($AST->deleteClause)
+             . $this->walkWhereClause($AST->whereClause);
+    }
+
+    /**
+     * Walks down an IdentificationVariable AST node, thereby generating the appropriate SQL.
+     * This one differs of ->walkIdentificationVariable() because it generates the entity identifiers.
+     *
+     * @param string $identVariable
+     * @return string
+     */
+    public function walkEntityIdentificationVariable($identVariable)
+    {
+        $class      = $this->_queryComponents[$identVariable]['metadata'];
+        $tableAlias = $this->getSQLTableAlias($class->getTableName(), $identVariable);
+        $sqlParts   = array();
+
+        foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
+            $sqlParts[] = $tableAlias . '.' . $columnName;
+        }
+
+        return implode(', ', $sqlParts);
+    }
+
+    /**
+     * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL.
+     *
+     * @param string $identificationVariable
+     * @param string $fieldName
+     * @return string The SQL.
+     */
+    public function walkIdentificationVariable($identificationVariable, $fieldName = null)
+    {
+        $class = $this->_queryComponents[$identificationVariable]['metadata'];
+
+        if (
+            $fieldName !== null && $class->isInheritanceTypeJoined() &&
+            isset($class->fieldMappings[$fieldName]['inherited'])
+        ) {
+            $class = $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited']);
+        }
+
+        return $this->getSQLTableAlias($class->getTableName(), $identificationVariable);
+    }
+
+    /**
+     * Walks down a PathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkPathExpression($pathExpr)
+    {
+        $sql = '';
+
+        switch ($pathExpr->type) {
+            case AST\PathExpression::TYPE_STATE_FIELD:
+                $fieldName = $pathExpr->field;
+                $dqlAlias = $pathExpr->identificationVariable;
+                $class = $this->_queryComponents[$dqlAlias]['metadata'];
+
+                if ($this->_useSqlTableAliases) {
+                    $sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.';
+                }
+
+                $sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
+                break;
+
+            case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
+                // 1- the owning side:
+                //    Just use the foreign key, i.e. u.group_id
+                $fieldName = $pathExpr->field;
+                $dqlAlias = $pathExpr->identificationVariable;
+                $class = $this->_queryComponents[$dqlAlias]['metadata'];
+
+                if (isset($class->associationMappings[$fieldName]['inherited'])) {
+                    $class = $this->_em->getClassMetadata($class->associationMappings[$fieldName]['inherited']);
+                }
+
+                $assoc = $class->associationMappings[$fieldName];
+
+                if ( ! $assoc['isOwningSide']) {
+                    throw QueryException::associationPathInverseSideNotSupported();
+                }
+
+                // COMPOSITE KEYS NOT (YET?) SUPPORTED
+                if (count($assoc['sourceToTargetKeyColumns']) > 1) {
+                    throw QueryException::associationPathCompositeKeyNotSupported();
+                }
+
+                if ($this->_useSqlTableAliases) {
+                    $sql .= $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.';
+                }
+
+                $sql .= reset($assoc['targetToSourceKeyColumns']);
+                break;
+
+            default:
+                throw QueryException::invalidPathExpression($pathExpr);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a SelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param $selectClause
+     * @return string The SQL.
+     */
+    public function walkSelectClause($selectClause)
+    {
+        $sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '');
+        $sqlSelectExpressions = array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions));
+
+        if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && $selectClause->isDistinct) {
+            $this->_query->setHint(self::HINT_DISTINCT, true);
+        }
+
+        $addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
+                $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT
+                ||
+                $this->_query->getHydrationMode() != Query::HYDRATE_OBJECT &&
+                $this->_query->getHint(Query::HINT_INCLUDE_META_COLUMNS);
+
+        foreach ($this->_selectedClasses as $selectedClass) {
+            $class       = $selectedClass['class'];
+            $dqlAlias    = $selectedClass['dqlAlias'];
+            $resultAlias = $selectedClass['resultAlias'];
+
+            // Register as entity or joined entity result
+            if ($this->_queryComponents[$dqlAlias]['relation'] === null) {
+                $this->_rsm->addEntityResult($class->name, $dqlAlias, $resultAlias);
+            } else {
+                $this->_rsm->addJoinedEntityResult(
+                    $class->name,
+                    $dqlAlias,
+                    $this->_queryComponents[$dqlAlias]['parent'],
+                    $this->_queryComponents[$dqlAlias]['relation']['fieldName']
+                );
+            }
+
+            if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
+                // Add discriminator columns to SQL
+                $rootClass   = $this->_em->getClassMetadata($class->rootEntityName);
+                $tblAlias    = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias);
+                $discrColumn = $rootClass->discriminatorColumn;
+                $columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
+
+                $sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
+
+                $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
+                $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']);
+            }
+
+            // Add foreign key columns to SQL, if necessary
+            if ( ! $addMetaColumns && ! $class->containsForeignIdentifier) {
+                continue;
+            }
+
+            // Add foreign key columns of class and also parent classes
+            foreach ($class->associationMappings as $assoc) {
+                if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) {
+                    continue;
+                } else if ( !$addMetaColumns && !isset($assoc['id'])) {
+                    continue;
+                }
+
+                $owningClass   = (isset($assoc['inherited'])) ? $this->_em->getClassMetadata($assoc['inherited']) : $class;
+                $sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias);
+
+                foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
+                    $columnAlias = $this->getSQLColumnAlias($srcColumn);
+
+                    $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
+
+                    $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
+                }
+            }
+
+            // Add foreign key columns to SQL, if necessary
+            if ( ! $addMetaColumns) {
+                continue;
+            }
+
+            // Add foreign key columns of subclasses
+            foreach ($class->subClasses as $subClassName) {
+                $subClass      = $this->_em->getClassMetadata($subClassName);
+                $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias);
+
+                foreach ($subClass->associationMappings as $assoc) {
+                    // Skip if association is inherited
+                    if (isset($assoc['inherited'])) continue;
+
+                    if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) continue;
+
+                    foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
+                        $columnAlias = $this->getSQLColumnAlias($srcColumn);
+
+                        $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
+
+                        $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn);
+                    }
+                }
+            }
+        }
+
+        $sql .= implode(', ', $sqlSelectExpressions);
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a FromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFromClause($fromClause)
+    {
+        $identificationVarDecls = $fromClause->identificationVariableDeclarations;
+        $sqlParts = array();
+
+        foreach ($identificationVarDecls as $identificationVariableDecl) {
+            $sql = '';
+
+            $rangeDecl = $identificationVariableDecl->rangeVariableDeclaration;
+            $dqlAlias = $rangeDecl->aliasIdentificationVariable;
+
+            $this->_rootAliases[] = $dqlAlias;
+
+            $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
+            $sql .= $class->getQuotedTableName($this->_platform) . ' '
+                  . $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            if ($class->isInheritanceTypeJoined()) {
+                $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
+            }
+
+            foreach ($identificationVariableDecl->joinVariableDeclarations as $joinVarDecl) {
+                $sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
+            }
+
+            if ($identificationVariableDecl->indexBy) {
+                $alias = $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable;
+                $field = $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field;
+
+                if (isset($this->_scalarFields[$alias][$field])) {
+                    $this->_rsm->addIndexByScalar($this->_scalarFields[$alias][$field]);
+                } else {
+                    $this->_rsm->addIndexBy(
+                        $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
+                        $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field
+                    );
+                }
+            }
+
+            $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE));
+        }
+
+        return ' FROM ' . implode(', ', $sqlParts);
+    }
+
+    /**
+     * Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFunction($function)
+    {
+        return $function->getSql($this);
+    }
+
+    /**
+     * Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByClause
+     * @return string The SQL.
+     */
+    public function walkOrderByClause($orderByClause)
+    {
+        $orderByItems = array_map(array($this, 'walkOrderByItem'), $orderByClause->orderByItems);
+
+        if (($collectionOrderByItems = $this->_generateOrderedCollectionOrderByItems()) !== '') {
+            $orderByItems = array_merge($orderByItems, (array) $collectionOrderByItems);
+        }
+
+        return ' ORDER BY ' . implode(', ', $orderByItems);
+    }
+
+    /**
+     * Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByItem
+     * @return string The SQL.
+     */
+    public function walkOrderByItem($orderByItem)
+    {
+        $expr = $orderByItem->expression;
+        $sql  = ($expr instanceof AST\PathExpression)
+            ? $this->walkPathExpression($expr)
+            : $this->walkResultVariable($this->_queryComponents[$expr]['token']['value']);
+
+        return $sql . ' ' . strtoupper($orderByItem->type);
+    }
+
+    /**
+     * Walks down a HavingClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param HavingClause
+     * @return string The SQL.
+     */
+    public function walkHavingClause($havingClause)
+    {
+        return ' HAVING ' . $this->walkConditionalExpression($havingClause->conditionalExpression);
+    }
+
+    /**
+     * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
+     *
+     * @param JoinVariableDeclaration $joinVarDecl
+     * @return string The SQL.
+     */
+    public function walkJoinVariableDeclaration($joinVarDecl)
+    {
+        $join     = $joinVarDecl->join;
+        $joinType = $join->joinType;
+        $sql      = ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER)
+            ? ' LEFT JOIN '
+            : ' INNER JOIN ';
+
+        if ($joinVarDecl->indexBy) {
+            // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently.
+            $this->_rsm->addIndexBy(
+                $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
+                $joinVarDecl->indexBy->simpleStateFieldPathExpression->field
+            );
+        }
+
+        $joinAssocPathExpr = $join->joinAssociationPathExpression;
+        $joinedDqlAlias    = $join->aliasIdentificationVariable;
+
+        $relation        = $this->_queryComponents[$joinedDqlAlias]['relation'];
+        $targetClass     = $this->_em->getClassMetadata($relation['targetEntity']);
+        $sourceClass     = $this->_em->getClassMetadata($relation['sourceEntity']);
+        $targetTableName = $targetClass->getQuotedTableName($this->_platform);
+
+        $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName(), $joinedDqlAlias);
+        $sourceTableAlias = $this->getSQLTableAlias($sourceClass->getTableName(), $joinAssocPathExpr->identificationVariable);
+
+        // Ensure we got the owning side, since it has all mapping info
+        $assoc = ( ! $relation['isOwningSide']) ? $targetClass->associationMappings[$relation['mappedBy']] : $relation;
+        if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && (!$this->_query->getHint(self::HINT_DISTINCT) || isset($this->_selectedClasses[$joinedDqlAlias]))) {
+            if ($relation['type'] == ClassMetadata::ONE_TO_MANY || $relation['type'] == ClassMetadata::MANY_TO_MANY) {
+                throw QueryException::iterateWithFetchJoinNotAllowed($assoc);
+            }
+        }
+
+        if ($joinVarDecl->indexBy) {
+            // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently.
+            $this->_rsm->addIndexBy(
+                $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
+                $joinVarDecl->indexBy->simpleStateFieldPathExpression->field
+            );
+        } else if (isset($relation['indexBy'])) {
+            $this->_rsm->addIndexBy($joinedDqlAlias, $relation['indexBy']);
+        }
+
+        // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot
+        // be the owning side and previously we ensured that $assoc is always the owning side of the associations.
+        // The owning side is necessary at this point because only it contains the JoinColumn information.
+        if ($assoc['type'] & ClassMetadata::TO_ONE) {
+            $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
+            $first = true;
+
+            foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
+                if ( ! $first) $sql .= ' AND '; else $first = false;
+
+                if ($relation['isOwningSide']) {
+                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) {
+                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
+                    }
+                    $sql .= $sourceTableAlias . '.' . $sourceColumn . ' = ' . $targetTableAlias . '.' . $quotedTargetColumn;
+                } else {
+                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) {
+                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform);
+                    }
+                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn;
+                }
+            }
+
+        } else if ($assoc['type'] == ClassMetadata::MANY_TO_MANY) {
+            // Join relation table
+            $joinTable = $assoc['joinTable'];
+            $joinTableAlias = $this->getSQLTableAlias($joinTable['name'], $joinedDqlAlias);
+            $sql .= $sourceClass->getQuotedJoinTableName($assoc, $this->_platform) . ' ' . $joinTableAlias . ' ON ';
+
+            $first = true;
+            if ($relation['isOwningSide']) {
+                foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) {
+                    if ( ! $first) $sql .= ' AND '; else $first = false;
+
+                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$sourceColumn])) {
+                        $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$sourceColumn], $this->_platform);
+                    }
+
+                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
+                }
+            } else {
+                foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) {
+                    if ( ! $first) $sql .= ' AND '; else $first = false;
+
+                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) {
+                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform);
+                    }
+
+                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
+                }
+            }
+
+            // Join target table
+            $sql .= ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) ? ' LEFT JOIN ' : ' INNER JOIN ';
+            $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
+
+            $first = true;
+            if ($relation['isOwningSide']) {
+                foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) {
+                    if ( ! $first) $sql .= ' AND '; else $first = false;
+
+                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) {
+                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
+                    }
+
+                    $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
+                }
+            } else {
+                foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) {
+                    if ( ! $first) $sql .= ' AND '; else $first = false;
+
+                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$sourceColumn])) {
+                        $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted.
+                    } else {
+                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$sourceColumn], $this->_platform);
+                    }
+
+                    $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
+                }
+            }
+        }
+
+        // Apply the filters
+        if ($filterExpr = $this->generateFilterConditionSQL($targetClass, $targetTableAlias)) {
+            $sql .= ' AND ' . $filterExpr;
+        }
+
+        // Handle WITH clause
+        if (($condExpr = $join->conditionalExpression) !== null) {
+            // Phase 2 AST optimization: Skip processment of ConditionalExpression
+            // if only one ConditionalTerm is defined
+            $sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
+        }
+
+        $discrSql = $this->_generateDiscriminatorColumnConditionSQL(array($joinedDqlAlias));
+
+        if ($discrSql) {
+            $sql .= ' AND ' . $discrSql;
+        }
+
+        // FIXME: these should either be nested or all forced to be left joins (DDC-XXX)
+        if ($targetClass->isInheritanceTypeJoined()) {
+            $sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a CaseExpression AST node and generates the corresponding SQL.
+     *
+     * @param CoalesceExpression|NullIfExpression|GeneralCaseExpression|SimpleCaseExpression $expression
+     * @return string The SQL.
+     */
+    public function walkCaseExpression($expression)
+    {
+        switch (true) {
+            case ($expression instanceof AST\CoalesceExpression):
+                return $this->walkCoalesceExpression($expression);
+
+            case ($expression instanceof AST\NullIfExpression):
+                return $this->walkNullIfExpression($expression);
+
+            case ($expression instanceof AST\GeneralCaseExpression):
+                return $this->walkGeneralCaseExpression($expression);
+
+            case ($expression instanceof AST\SimpleCaseExpression):
+                return $this->walkSimpleCaseExpression($expression);
+
+            default:
+                return '';
+        }
+    }
+
+    /**
+     * Walks down a CoalesceExpression AST node and generates the corresponding SQL.
+     *
+     * @param CoalesceExpression $coalesceExpression
+     * @return string The SQL.
+     */
+    public function walkCoalesceExpression($coalesceExpression)
+    {
+        $sql = 'COALESCE(';
+
+        $scalarExpressions = array();
+
+        foreach ($coalesceExpression->scalarExpressions as $scalarExpression) {
+            $scalarExpressions[] = $this->walkSimpleArithmeticExpression($scalarExpression);
+        }
+
+        $sql .= implode(', ', $scalarExpressions) . ')';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a NullIfExpression AST node and generates the corresponding SQL.
+     *
+     * @param NullIfExpression $nullIfExpression
+     * @return string The SQL.
+     */
+    public function walkNullIfExpression($nullIfExpression)
+    {
+        $firstExpression = is_string($nullIfExpression->firstExpression)
+            ? $this->_conn->quote($nullIfExpression->firstExpression)
+            : $this->walkSimpleArithmeticExpression($nullIfExpression->firstExpression);
+
+        $secondExpression = is_string($nullIfExpression->secondExpression)
+            ? $this->_conn->quote($nullIfExpression->secondExpression)
+            : $this->walkSimpleArithmeticExpression($nullIfExpression->secondExpression);
+
+        return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')';
+    }
+
+    /**
+     * Walks down a GeneralCaseExpression AST node and generates the corresponding SQL.
+     *
+     * @param GeneralCaseExpression $generalCaseExpression
+     * @return string The SQL.
+     */
+    public function walkGeneralCaseExpression(AST\GeneralCaseExpression $generalCaseExpression)
+    {
+        $sql = 'CASE';
+
+        foreach ($generalCaseExpression->whenClauses as $whenClause) {
+            $sql .= ' WHEN ' . $this->walkConditionalExpression($whenClause->caseConditionExpression);
+            $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($whenClause->thenScalarExpression);
+        }
+
+        $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($generalCaseExpression->elseScalarExpression) . ' END';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a SimpleCaseExpression AST node and generates the corresponding SQL.
+     *
+     * @param SimpleCaseExpression $simpleCaseExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleCaseExpression($simpleCaseExpression)
+    {
+        $sql = 'CASE ' . $this->walkStateFieldPathExpression($simpleCaseExpression->caseOperand);
+
+        foreach ($simpleCaseExpression->simpleWhenClauses as $simpleWhenClause) {
+            $sql .= ' WHEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->caseScalarExpression);
+            $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->thenScalarExpression);
+        }
+
+        $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($simpleCaseExpression->elseScalarExpression) . ' END';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a SelectExpression AST node and generates the corresponding SQL.
+     *
+     * @param SelectExpression $selectExpression
+     * @return string The SQL.
+     */
+    public function walkSelectExpression($selectExpression)
+    {
+        $sql    = '';
+        $expr   = $selectExpression->expression;
+        $hidden = $selectExpression->hiddenAliasResultVariable;
+
+        switch (true) {
+            case ($expr instanceof AST\PathExpression):
+                if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) {
+                    throw QueryException::invalidPathExpression($expr->type);
+                }
+
+                $fieldName = $expr->field;
+                $dqlAlias  = $expr->identificationVariable;
+                $qComp     = $this->_queryComponents[$dqlAlias];
+                $class     = $qComp['metadata'];
+
+                $resultAlias = $selectExpression->fieldIdentificationVariable ?: $fieldName;
+                $tableName   = ($class->isInheritanceTypeJoined())
+                    ? $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName)
+                    : $class->getTableName();
+
+                $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
+                $columnName    = $class->getQuotedColumnName($fieldName, $this->_platform);
+                $columnAlias   = $this->getSQLColumnAlias($class->fieldMappings[$fieldName]['columnName']);
+
+                $col = $sqlTableAlias . '.' . $columnName;
+
+                $fieldType = $class->getTypeOfField($fieldName);
+
+                if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
+                    $type = Type::getType($fieldType);
+                    $col  = $type->convertToPHPValueSQL($col, $this->_conn->getDatabasePlatform());
+                }
+
+                $sql .= $col . ' AS ' . $columnAlias;
+
+                $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
+
+                if ( ! $hidden) {
+                    $this->_rsm->addScalarResult($columnAlias, $resultAlias, $fieldType);
+                    $this->_scalarFields[$dqlAlias][$fieldName] = $columnAlias;
+                }
+                break;
+
+            case ($expr instanceof AST\AggregateExpression):
+            case ($expr instanceof AST\Functions\FunctionNode):
+            case ($expr instanceof AST\SimpleArithmeticExpression):
+            case ($expr instanceof AST\ArithmeticTerm):
+            case ($expr instanceof AST\ArithmeticFactor):
+            case ($expr instanceof AST\ArithmeticPrimary):
+            case ($expr instanceof AST\Literal):
+            case ($expr instanceof AST\NullIfExpression):
+            case ($expr instanceof AST\CoalesceExpression):
+            case ($expr instanceof AST\GeneralCaseExpression):
+            case ($expr instanceof AST\SimpleCaseExpression):
+                $columnAlias = $this->getSQLColumnAlias('sclr');
+                $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
+
+                $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias;
+
+                $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
+
+                if ( ! $hidden) {
+                    // We cannot resolve field type here; assume 'string'.
+                    $this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string');
+                }
+                break;
+
+            case ($expr instanceof AST\Subselect):
+                $columnAlias = $this->getSQLColumnAlias('sclr');
+                $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
+
+                $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
+
+                $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
+
+                if ( ! $hidden) {
+                    // We cannot resolve field type here; assume 'string'.
+                    $this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string');
+                }
+                break;
+
+            default:
+                // IdentificationVariable or PartialObjectExpression
+                if ($expr instanceof AST\PartialObjectExpression) {
+                    $dqlAlias = $expr->identificationVariable;
+                    $partialFieldSet = $expr->partialFieldSet;
+                } else {
+                    $dqlAlias = $expr;
+                    $partialFieldSet = array();
+                }
+
+                $queryComp   = $this->_queryComponents[$dqlAlias];
+                $class       = $queryComp['metadata'];
+                $resultAlias = $selectExpression->fieldIdentificationVariable ?: null;
+
+                if ( ! isset($this->_selectedClasses[$dqlAlias])) {
+                    $this->_selectedClasses[$dqlAlias] = array(
+                        'class'       => $class,
+                        'dqlAlias'    => $dqlAlias,
+                        'resultAlias' => $resultAlias
+                    );
+                }
+
+                $sqlParts = array();
+
+                // Select all fields from the queried class
+                foreach ($class->fieldMappings as $fieldName => $mapping) {
+                    if ($partialFieldSet && ! in_array($fieldName, $partialFieldSet)) {
+                        continue;
+                    }
+
+                    $tableName = (isset($mapping['inherited']))
+                        ? $this->_em->getClassMetadata($mapping['inherited'])->getTableName()
+                        : $class->getTableName();
+
+                    $sqlTableAlias    = $this->getSQLTableAlias($tableName, $dqlAlias);
+                    $columnAlias      = $this->getSQLColumnAlias($mapping['columnName']);
+                    $quotedColumnName = $class->getQuotedColumnName($fieldName, $this->_platform);
+
+                    $col = $sqlTableAlias . '.' . $quotedColumnName;
+
+                    if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
+                        $type = Type::getType($class->getTypeOfField($fieldName));
+                        $col = $type->convertToPHPValueSQL($col, $this->_platform);
+                    }
+
+                    $sqlParts[] = $col . ' AS '. $columnAlias;
+
+                    $this->_scalarResultAliasMap[$resultAlias][] = $columnAlias;
+
+                    $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
+                }
+
+                // Add any additional fields of subclasses (excluding inherited fields)
+                // 1) on Single Table Inheritance: always, since its marginal overhead
+                // 2) on Class Table Inheritance only if partial objects are disallowed,
+                //    since it requires outer joining subtables.
+                if ($class->isInheritanceTypeSingleTable() || ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
+                    foreach ($class->subClasses as $subClassName) {
+                        $subClass      = $this->_em->getClassMetadata($subClassName);
+                        $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias);
+
+                        foreach ($subClass->fieldMappings as $fieldName => $mapping) {
+                            if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
+                                continue;
+                            }
+
+                            $columnAlias      = $this->getSQLColumnAlias($mapping['columnName']);
+                            $quotedColumnName = $subClass->getQuotedColumnName($fieldName, $this->_platform);
+
+                            $col = $sqlTableAlias . '.' . $quotedColumnName;
+
+                            if (isset($subClass->fieldMappings[$fieldName]['requireSQLConversion'])) {
+                                $type = Type::getType($subClass->getTypeOfField($fieldName));
+                                $col = $type->convertToPHPValueSQL($col, $this->_platform);
+                            }
+
+                            $sqlParts[] = $col . ' AS ' . $columnAlias;
+
+                            $this->_scalarResultAliasMap[$resultAlias][] = $columnAlias;
+
+                            $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
+                        }
+                    }
+                }
+
+                $sql .= implode(', ', $sqlParts);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param QuantifiedExpression
+     * @return string The SQL.
+     */
+    public function walkQuantifiedExpression($qExpr)
+    {
+        return ' ' . strtoupper($qExpr->type) . '(' . $this->walkSubselect($qExpr->subselect) . ')';
+    }
+
+    /**
+     * Walks down a Subselect AST node, thereby generating the appropriate SQL.
+     *
+     * @param Subselect
+     * @return string The SQL.
+     */
+    public function walkSubselect($subselect)
+    {
+        $useAliasesBefore  = $this->_useSqlTableAliases;
+        $rootAliasesBefore = $this->_rootAliases;
+
+        $this->_rootAliases = array(); // reset the rootAliases for the subselect
+        $this->_useSqlTableAliases = true;
+
+        $sql  = $this->walkSimpleSelectClause($subselect->simpleSelectClause);
+        $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause);
+        $sql .= $this->walkWhereClause($subselect->whereClause);
+
+        $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : '';
+        $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : '';
+        $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : '';
+
+        $this->_rootAliases        = $rootAliasesBefore; // put the main aliases back
+        $this->_useSqlTableAliases = $useAliasesBefore;
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SubselectFromClause
+     * @return string The SQL.
+     */
+    public function walkSubselectFromClause($subselectFromClause)
+    {
+        $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations;
+        $sqlParts = array ();
+
+        foreach ($identificationVarDecls as $subselectIdVarDecl) {
+            $sql = '';
+
+            $rangeDecl = $subselectIdVarDecl->rangeVariableDeclaration;
+            $dqlAlias  = $rangeDecl->aliasIdentificationVariable;
+
+            $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
+            $sql .= $class->getQuotedTableName($this->_platform) . ' '
+                  . $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            $this->_rootAliases[] = $dqlAlias;
+
+            if ($class->isInheritanceTypeJoined()) {
+                $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
+            }
+
+            foreach ($subselectIdVarDecl->joinVariableDeclarations as $joinVarDecl) {
+                $sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
+            }
+
+            $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE));
+        }
+
+        return ' FROM ' . implode(', ', $sqlParts);
+    }
+
+    /**
+     * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectClause
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectClause($simpleSelectClause)
+    {
+        return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '')
+             . $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression);
+    }
+
+    /**
+     * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectExpression($simpleSelectExpression)
+    {
+        $expr = $simpleSelectExpression->expression;
+        $sql  = ' ';
+
+        switch (true) {
+            case ($expr instanceof AST\PathExpression):
+                $sql .= $this->walkPathExpression($expr);
+                break;
+
+            case ($expr instanceof AST\AggregateExpression):
+                $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
+
+                $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias;
+                break;
+
+            case ($expr instanceof AST\Subselect):
+                $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
+
+                $columnAlias = 'sclr' . $this->_aliasCounter++;
+                $this->_scalarResultAliasMap[$alias] = $columnAlias;
+
+                $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
+                break;
+
+            case ($expr instanceof AST\Functions\FunctionNode):
+            case ($expr instanceof AST\SimpleArithmeticExpression):
+            case ($expr instanceof AST\ArithmeticTerm):
+            case ($expr instanceof AST\ArithmeticFactor):
+            case ($expr instanceof AST\ArithmeticPrimary):
+            case ($expr instanceof AST\Literal):
+            case ($expr instanceof AST\NullIfExpression):
+            case ($expr instanceof AST\CoalesceExpression):
+            case ($expr instanceof AST\GeneralCaseExpression):
+            case ($expr instanceof AST\SimpleCaseExpression):
+                $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
+
+                $columnAlias = $this->getSQLColumnAlias('sclr');
+                $this->_scalarResultAliasMap[$alias] = $columnAlias;
+
+                $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias;
+                break;
+
+            default: // IdentificationVariable
+                $sql .= $this->walkEntityIdentificationVariable($expr);
+                break;
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param AggregateExpression
+     * @return string The SQL.
+     */
+    public function walkAggregateExpression($aggExpression)
+    {
+        return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '')
+             . $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')';
+    }
+
+    /**
+     * Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByClause
+     * @return string The SQL.
+     */
+    public function walkGroupByClause($groupByClause)
+    {
+        $sqlParts = array();
+
+        foreach ($groupByClause->groupByItems AS $groupByItem) {
+            $sqlParts[] = $this->walkGroupByItem($groupByItem);
+        }
+
+        return ' GROUP BY ' . implode(', ', $sqlParts);
+    }
+
+    /**
+     * Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByItem
+     * @return string The SQL.
+     */
+    public function walkGroupByItem($groupByItem)
+    {
+        // StateFieldPathExpression
+        if ( ! is_string($groupByItem)) {
+            return $this->walkPathExpression($groupByItem);
+        }
+
+        // ResultVariable
+        if (isset($this->_queryComponents[$groupByItem]['resultVariable'])) {
+            return $this->walkResultVariable($groupByItem);
+        }
+
+        // IdentificationVariable
+        $sqlParts = array();
+
+        foreach ($this->_queryComponents[$groupByItem]['metadata']->fieldNames AS $field) {
+            $item       = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $field);
+            $item->type = AST\PathExpression::TYPE_STATE_FIELD;
+
+            $sqlParts[] = $this->walkPathExpression($item);
+        }
+
+        foreach ($this->_queryComponents[$groupByItem]['metadata']->associationMappings AS $mapping) {
+            if ($mapping['isOwningSide'] && $mapping['type'] & ClassMetadataInfo::TO_ONE) {
+                $item       = new AST\PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $groupByItem, $mapping['fieldName']);
+                $item->type = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
+
+                $sqlParts[] = $this->walkPathExpression($item);
+            }
+        }
+
+        return implode(', ', $sqlParts);
+    }
+
+    /**
+     * Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteClause
+     * @return string The SQL.
+     */
+    public function walkDeleteClause(AST\DeleteClause $deleteClause)
+    {
+        $class     = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
+        $tableName = $class->getTableName();
+        $sql       = 'DELETE FROM ' . $class->getQuotedTableName($this->_platform);
+
+        $this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable);
+        $this->_rootAliases[] = $deleteClause->aliasIdentificationVariable;
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateClause
+     * @return string The SQL.
+     */
+    public function walkUpdateClause($updateClause)
+    {
+        $class     = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
+        $tableName = $class->getTableName();
+        $sql       = 'UPDATE ' . $class->getQuotedTableName($this->_platform);
+
+        $this->setSQLTableAlias($tableName, $tableName, $updateClause->aliasIdentificationVariable);
+        $this->_rootAliases[] = $updateClause->aliasIdentificationVariable;
+
+        $sql .= ' SET ' . implode(', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems));
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateItem
+     * @return string The SQL.
+     */
+    public function walkUpdateItem($updateItem)
+    {
+        $useTableAliasesBefore = $this->_useSqlTableAliases;
+        $this->_useSqlTableAliases = false;
+
+        $sql      = $this->walkPathExpression($updateItem->pathExpression) . ' = ';
+        $newValue = $updateItem->newValue;
+
+        switch (true) {
+            case ($newValue instanceof AST\Node):
+                $sql .= $newValue->dispatch($this);
+                break;
+
+            case ($newValue === null):
+                $sql .= 'NULL';
+                break;
+
+            default:
+                $sql .= $this->_conn->quote($newValue);
+                break;
+        }
+
+        $this->_useSqlTableAliases = $useTableAliasesBefore;
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a WhereClause AST node, thereby generating the appropriate SQL.
+     * WhereClause or not, the appropriate discriminator sql is added.
+     *
+     * @param WhereClause
+     * @return string The SQL.
+     */
+    public function walkWhereClause($whereClause)
+    {
+        $condSql  = null !== $whereClause ? $this->walkConditionalExpression($whereClause->conditionalExpression) : '';
+        $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_rootAliases);
+
+        if ($this->_em->hasFilters()) {
+            $filterClauses = array();
+            foreach ($this->_rootAliases as $dqlAlias) {
+                $class = $this->_queryComponents[$dqlAlias]['metadata'];
+                $tableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
+
+                if ($filterExpr = $this->generateFilterConditionSQL($class, $tableAlias)) {
+                    $filterClauses[] = $filterExpr;
+                }
+            }
+
+            if (count($filterClauses)) {
+                if ($condSql) {
+                    $condSql .= ' AND ';
+                }
+
+                $condSql .= implode(' AND ', $filterClauses);
+            }
+        }
+
+        if ($condSql) {
+            return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql);
+        }
+
+        if ($discrSql) {
+            return ' WHERE ' . $discrSql;
+        }
+
+        return '';
+    }
+
+    /**
+     * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalExpression
+     * @return string The SQL.
+     */
+    public function walkConditionalExpression($condExpr)
+    {
+        // Phase 2 AST optimization: Skip processment of ConditionalExpression
+        // if only one ConditionalTerm is defined
+        if ( ! ($condExpr instanceof AST\ConditionalExpression)) {
+            return $this->walkConditionalTerm($condExpr);
+        }
+
+        return implode(' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms));
+    }
+
+    /**
+     * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalTerm
+     * @return string The SQL.
+     */
+    public function walkConditionalTerm($condTerm)
+    {
+        // Phase 2 AST optimization: Skip processment of ConditionalTerm
+        // if only one ConditionalFactor is defined
+        if ( ! ($condTerm instanceof AST\ConditionalTerm)) {
+            return $this->walkConditionalFactor($condTerm);
+        }
+
+        return implode(' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors));
+    }
+
+    /**
+     * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalFactor
+     * @return string The SQL.
+     */
+    public function walkConditionalFactor($factor)
+    {
+        // Phase 2 AST optimization: Skip processment of ConditionalFactor
+        // if only one ConditionalPrimary is defined
+        return ( ! ($factor instanceof AST\ConditionalFactor))
+            ? $this->walkConditionalPrimary($factor)
+            : ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary);
+    }
+
+    /**
+     * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalPrimary
+     * @return string The SQL.
+     */
+    public function walkConditionalPrimary($primary)
+    {
+        if ($primary->isSimpleConditionalExpression()) {
+            return $primary->simpleConditionalExpression->dispatch($this);
+        }
+
+        if ($primary->isConditionalExpression()) {
+            $condExpr = $primary->conditionalExpression;
+
+            return '(' . $this->walkConditionalExpression($condExpr) . ')';
+        }
+    }
+
+    /**
+     * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ExistsExpression
+     * @return string The SQL.
+     */
+    public function walkExistsExpression($existsExpr)
+    {
+        $sql = ($existsExpr->not) ? 'NOT ' : '';
+
+        $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->subselect) . ')';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param CollectionMemberExpression
+     * @return string The SQL.
+     */
+    public function walkCollectionMemberExpression($collMemberExpr)
+    {
+        $sql = $collMemberExpr->not ? 'NOT ' : '';
+        $sql .= 'EXISTS (SELECT 1 FROM ';
+
+        $entityExpr   = $collMemberExpr->entityExpression;
+        $collPathExpr = $collMemberExpr->collectionValuedPathExpression;
+
+        $fieldName = $collPathExpr->field;
+        $dqlAlias  = $collPathExpr->identificationVariable;
+
+        $class = $this->_queryComponents[$dqlAlias]['metadata'];
+
+        switch (true) {
+            // InputParameter
+            case ($entityExpr instanceof AST\InputParameter):
+                $dqlParamKey = $entityExpr->name;
+                $entity      = $this->_query->getParameter($dqlParamKey);
+                $entitySql   = '?';
+                break;
+
+            // SingleValuedAssociationPathExpression | IdentificationVariable
+            case ($entityExpr instanceof AST\PathExpression):
+                $entitySql = $this->walkPathExpression($entityExpr);
+                break;
+
+            default:
+                throw new \BadMethodCallException("Not implemented");
+        }
+
+        $assoc = $class->associationMappings[$fieldName];
+
+        if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) {
+            $targetClass      = $this->_em->getClassMetadata($assoc['targetEntity']);
+            $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName());
+            $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            $sql .= $targetClass->getQuotedTableName($this->_platform) . ' ' . $targetTableAlias . ' WHERE ';
+
+            $owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']];
+            $sqlParts    = array();
+
+            foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) {
+                $targetColumn = $class->getQuotedColumnName($class->fieldNames[$targetColumn], $this->_platform);
+
+                $sqlParts[] = $sourceTableAlias . '.' . $targetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn;
+            }
+
+            foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
+                if (isset($dqlParamKey)) {
+                    $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
+                }
+
+                $sqlParts[] = $targetTableAlias . '.'  . $targetColumnName . ' = ' . $entitySql;
+            }
+
+            $sql .= implode(' AND ', $sqlParts);
+        } else { // many-to-many
+            $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
+
+            $owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']];
+            $joinTable = $owningAssoc['joinTable'];
+
+            // SQL table aliases
+            $joinTableAlias   = $this->getSQLTableAlias($joinTable['name']);
+            $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName());
+            $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+
+            // join to target table
+            $sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $this->_platform) . ' ' . $joinTableAlias
+                  . ' INNER JOIN ' . $targetClass->getQuotedTableName($this->_platform) . ' ' . $targetTableAlias . ' ON ';
+
+            // join conditions
+            $joinColumns  = $assoc['isOwningSide'] ? $joinTable['inverseJoinColumns'] : $joinTable['joinColumns'];
+            $joinSqlParts = array();
+
+            foreach ($joinColumns as $joinColumn) {
+                $targetColumn = $targetClass->getQuotedColumnName(
+                    $targetClass->fieldNames[$joinColumn['referencedColumnName']],
+                    $this->_platform
+                );
+
+                $joinSqlParts[] = $joinTableAlias . '.' . $joinColumn['name'] . ' = ' . $targetTableAlias . '.' . $targetColumn;
+            }
+
+            $sql .= implode(' AND ', $joinSqlParts);
+            $sql .= ' WHERE ';
+
+            $joinColumns = $assoc['isOwningSide'] ? $joinTable['joinColumns'] : $joinTable['inverseJoinColumns'];
+            $sqlParts    = array();
+
+            foreach ($joinColumns as $joinColumn) {
+                $targetColumn = $class->getQuotedColumnName(
+                    $class->fieldNames[$joinColumn['referencedColumnName']],
+                    $this->_platform
+                );
+
+                $sqlParts[] = $joinTableAlias . '.' . $joinColumn['name'] . ' = ' . $sourceTableAlias . '.' . $targetColumn;
+            }
+
+            foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
+                if (isset($dqlParamKey)) {
+                    $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
+                }
+
+                $sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' = ' . $entitySql;
+            }
+
+            $sql .= implode(' AND ', $sqlParts);
+        }
+
+        return $sql . ')';
+    }
+
+    /**
+     * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param EmptyCollectionComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr)
+    {
+        $sizeFunc = new AST\Functions\SizeFunction('size');
+        $sizeFunc->collectionPathExpression = $emptyCollCompExpr->expression;
+
+        return $sizeFunc->getSql($this) . ($emptyCollCompExpr->not ? ' > 0' : ' = 0');
+    }
+
+    /**
+     * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param NullComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkNullComparisonExpression($nullCompExpr)
+    {
+        $sql = '';
+        $innerExpr = $nullCompExpr->expression;
+
+        if ($innerExpr instanceof AST\InputParameter) {
+            $dqlParamKey = $innerExpr->name;
+            $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
+            $sql .= ' ?';
+        } else {
+            $sql .= $this->walkPathExpression($innerExpr);
+        }
+
+        $sql .= ' IS' . ($nullCompExpr->not ? ' NOT' : '') . ' NULL';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an InExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InExpression
+     * @return string The SQL.
+     */
+    public function walkInExpression($inExpr)
+    {
+        $sql = $this->walkArithmeticExpression($inExpr->expression) . ($inExpr->not ? ' NOT' : '') . ' IN (';
+
+        $sql .= ($inExpr->subselect)
+            ? $this->walkSubselect($inExpr->subselect)
+            : implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals));
+
+        $sql .= ')';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InstanceOfExpression
+     * @return string The SQL.
+     */
+    public function walkInstanceOfExpression($instanceOfExpr)
+    {
+        $sql = '';
+
+        $dqlAlias = $instanceOfExpr->identificationVariable;
+        $discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata'];
+        $fieldName = null;
+
+        if ($class->discriminatorColumn) {
+            $discrClass = $this->_em->getClassMetadata($class->rootEntityName);
+        }
+
+        if ($this->_useSqlTableAliases) {
+            $sql .= $this->getSQLTableAlias($discrClass->getTableName(), $dqlAlias) . '.';
+        }
+
+        $sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
+
+        $sqlParameterList = array();
+
+        foreach ($instanceOfExpr->value as $parameter) {
+            if ($parameter instanceof AST\InputParameter) {
+                // We need to modify the parameter value to be its correspondent mapped value
+                $dqlParamKey = $parameter->name;
+                $paramValue  = $this->_query->getParameter($dqlParamKey);
+
+                if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
+                    throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
+                }
+
+                $entityClassName = $paramValue->name;
+            } else {
+                // Get name from ClassMetadata to resolve aliases.
+                $entityClassName = $this->_em->getClassMetadata($parameter)->name;
+            }
+
+            if ($entityClassName == $class->name) {
+                $sqlParameterList[] = $this->_conn->quote($class->discriminatorValue);
+            } else {
+                $discrMap = array_flip($class->discriminatorMap);
+
+                if (!isset($discrMap[$entityClassName])) {
+                    throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
+                }
+
+                $sqlParameterList[] = $this->_conn->quote($discrMap[$entityClassName]);
+            }
+        }
+
+        $sql .= '(' . implode(', ', $sqlParameterList) . ')';
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an InParameter AST node, thereby generating the appropriate SQL.
+     *
+     * @param InParameter
+     * @return string The SQL.
+     */
+    public function walkInParameter($inParam)
+    {
+        return $inParam instanceof AST\InputParameter
+            ? $this->walkInputParameter($inParam)
+            : $this->walkLiteral($inParam);
+    }
+
+    /**
+     * Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkLiteral($literal)
+    {
+        switch ($literal->type) {
+            case AST\Literal::STRING:
+                return $this->_conn->quote($literal->value);
+
+            case AST\Literal::BOOLEAN:
+                $bool = strtolower($literal->value) == 'true' ? true : false;
+                $boolVal = $this->_conn->getDatabasePlatform()->convertBooleans($bool);
+
+                return $boolVal;
+
+            case AST\Literal::NUMERIC:
+                return $literal->value;
+
+            default:
+                throw QueryException::invalidLiteral($literal);
+        }
+    }
+
+    /**
+     * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param BetweenExpression
+     * @return string The SQL.
+     */
+    public function walkBetweenExpression($betweenExpr)
+    {
+        $sql = $this->walkArithmeticExpression($betweenExpr->expression);
+
+        if ($betweenExpr->not) $sql .= ' NOT';
+
+        $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression)
+              . ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression);
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param LikeExpression
+     * @return string The SQL.
+     */
+    public function walkLikeExpression($likeExpr)
+    {
+        $stringExpr = $likeExpr->stringExpression;
+        $sql = $stringExpr->dispatch($this) . ($likeExpr->not ? ' NOT' : '') . ' LIKE ';
+
+        if ($likeExpr->stringPattern instanceof AST\InputParameter) {
+            $inputParam = $likeExpr->stringPattern;
+            $dqlParamKey = $inputParam->name;
+            $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
+            $sql .= '?';
+        } else {
+            $sql .= $this->_conn->quote($likeExpr->stringPattern);
+        }
+
+        if ($likeExpr->escapeChar) {
+            $sql .= ' ESCAPE ' . $this->_conn->quote($likeExpr->escapeChar);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param StateFieldPathExpression
+     * @return string The SQL.
+     */
+    public function walkStateFieldPathExpression($stateFieldPathExpression)
+    {
+        return $this->walkPathExpression($stateFieldPathExpression);
+    }
+
+    /**
+     * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkComparisonExpression($compExpr)
+    {
+        $leftExpr  = $compExpr->leftExpression;
+        $rightExpr = $compExpr->rightExpression;
+        $sql       = '';
+
+        $sql .= ($leftExpr instanceof AST\Node)
+            ? $leftExpr->dispatch($this)
+            : (is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr));
+
+        $sql .= ' ' . $compExpr->operator . ' ';
+
+        $sql .= ($rightExpr instanceof AST\Node)
+            ? $rightExpr->dispatch($this)
+            : (is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr));
+
+        return $sql;
+    }
+
+    /**
+     * Walks down an InputParameter AST node, thereby generating the appropriate SQL.
+     *
+     * @param InputParameter
+     * @return string The SQL.
+     */
+    public function walkInputParameter($inputParam)
+    {
+        $this->_parserResult->addParameterMapping($inputParam->name, $this->_sqlParamIndex++);
+
+        return '?';
+    }
+
+    /**
+     * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkArithmeticExpression($arithmeticExpr)
+    {
+        return ($arithmeticExpr->isSimpleArithmeticExpression())
+        	? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression)
+        	: '(' . $this->walkSubselect($arithmeticExpr->subselect) . ')';
+    }
+
+    /**
+     * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleArithmeticExpression($simpleArithmeticExpr)
+    {
+        if ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) {
+            return $this->walkArithmeticTerm($simpleArithmeticExpr);
+        }
+
+        return implode(' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms));
+    }
+
+    /**
+     * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticTerm($term)
+    {
+        if (is_string($term)) {
+            return (isset($this->_queryComponents[$term]))
+                ? $this->walkResultVariable($this->_queryComponents[$term]['token']['value'])
+                : $term;
+        }
+
+        // Phase 2 AST optimization: Skip processment of ArithmeticTerm
+        // if only one ArithmeticFactor is defined
+        if ( ! ($term instanceof AST\ArithmeticTerm)) {
+            return $this->walkArithmeticFactor($term);
+        }
+
+        return implode(' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors));
+    }
+
+    /**
+     * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticFactor($factor)
+    {
+        if (is_string($factor)) {
+            return $factor;
+        }
+
+        // Phase 2 AST optimization: Skip processment of ArithmeticFactor
+        // if only one ArithmeticPrimary is defined
+        if ( ! ($factor instanceof AST\ArithmeticFactor)) {
+            return $this->walkArithmeticPrimary($factor);
+        }
+
+        $sign = $factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '');
+
+        return $sign . $this->walkArithmeticPrimary($factor->arithmeticPrimary);
+    }
+
+    /**
+     * Walks down an ArithmeticPrimary that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticPrimary($primary)
+    {
+        if ($primary instanceof AST\SimpleArithmeticExpression) {
+            return '(' . $this->walkSimpleArithmeticExpression($primary) . ')';
+        }
+
+        if ($primary instanceof AST\Node) {
+            return $primary->dispatch($this);
+        }
+
+        return $this->walkEntityIdentificationVariable($primary);
+    }
+
+    /**
+     * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkStringPrimary($stringPrimary)
+    {
+        return (is_string($stringPrimary))
+            ? $this->_conn->quote($stringPrimary)
+            : $stringPrimary->dispatch($this);
+    }
+
+    /**
+     * Walks down a ResultVriable that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param string $resultVariable
+     * @return string The SQL.
+     */
+    public function walkResultVariable($resultVariable)
+    {
+        $resultAlias = $this->_scalarResultAliasMap[$resultVariable];
+
+        if (is_array($resultAlias)) {
+            return implode(', ', $resultAlias);
+        }
+
+        return $resultAlias;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalker.php	(revision 345)
@@ -0,0 +1,411 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * Interface for walkers of DQL ASTs (abstract syntax trees).
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+interface TreeWalker
+{
+    /**
+     * Initializes TreeWalker with important information about the ASTs to be walked
+     *
+     * @param Query $query The parsed Query.
+     * @param ParserResult $parserResult The result of the parsing process.
+     * @param array $queryComponents Query components (symbol table)
+     */
+    public function __construct($query, $parserResult, array $queryComponents);
+
+    /**
+     * Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    function walkSelectStatement(AST\SelectStatement $AST);
+
+    /**
+     * Walks down a SelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    function walkSelectClause($selectClause);
+
+    /**
+     * Walks down a FromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    function walkFromClause($fromClause);
+
+    /**
+     * Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    function walkFunction($function);
+
+    /**
+     * Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByClause
+     * @return string The SQL.
+     */
+    function walkOrderByClause($orderByClause);
+
+    /**
+     * Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByItem
+     * @return string The SQL.
+     */
+    function walkOrderByItem($orderByItem);
+
+    /**
+     * Walks down a HavingClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param HavingClause
+     * @return string The SQL.
+     */
+    function walkHavingClause($havingClause);
+
+    /**
+     * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
+     *
+     * @param JoinVariableDeclaration $joinVarDecl
+     * @return string The SQL.
+     */
+    function walkJoinVariableDeclaration($joinVarDecl);
+
+    /**
+     * Walks down a SelectExpression AST node and generates the corresponding SQL.
+     *
+     * @param SelectExpression $selectExpression
+     * @return string The SQL.
+     */
+    function walkSelectExpression($selectExpression);
+
+    /**
+     * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param QuantifiedExpression
+     * @return string The SQL.
+     */
+    function walkQuantifiedExpression($qExpr);
+
+    /**
+     * Walks down a Subselect AST node, thereby generating the appropriate SQL.
+     *
+     * @param Subselect
+     * @return string The SQL.
+     */
+    function walkSubselect($subselect);
+
+    /**
+     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SubselectFromClause
+     * @return string The SQL.
+     */
+    function walkSubselectFromClause($subselectFromClause);
+
+    /**
+     * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectClause
+     * @return string The SQL.
+     */
+    function walkSimpleSelectClause($simpleSelectClause);
+
+    /**
+     * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectExpression
+     * @return string The SQL.
+     */
+    function walkSimpleSelectExpression($simpleSelectExpression);
+
+    /**
+     * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param AggregateExpression
+     * @return string The SQL.
+     */
+    function walkAggregateExpression($aggExpression);
+
+    /**
+     * Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByClause
+     * @return string The SQL.
+     */
+    function walkGroupByClause($groupByClause);
+
+    /**
+     * Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByItem
+     * @return string The SQL.
+     */
+    function walkGroupByItem($groupByItem);
+
+    /**
+     * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateStatement
+     * @return string The SQL.
+     */
+    function walkUpdateStatement(AST\UpdateStatement $AST);
+
+    /**
+     * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteStatement
+     * @return string The SQL.
+     */
+    function walkDeleteStatement(AST\DeleteStatement $AST);
+
+    /**
+     * Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteClause
+     * @return string The SQL.
+     */
+    function walkDeleteClause(AST\DeleteClause $deleteClause);
+
+    /**
+     * Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateClause
+     * @return string The SQL.
+     */
+    function walkUpdateClause($updateClause);
+
+    /**
+     * Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateItem
+     * @return string The SQL.
+     */
+    function walkUpdateItem($updateItem);
+
+    /**
+     * Walks down a WhereClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param WhereClause
+     * @return string The SQL.
+     */
+    function walkWhereClause($whereClause);
+
+    /**
+     * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalExpression
+     * @return string The SQL.
+     */
+    function walkConditionalExpression($condExpr);
+
+    /**
+     * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalTerm
+     * @return string The SQL.
+     */
+    function walkConditionalTerm($condTerm);
+
+    /**
+     * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalFactor
+     * @return string The SQL.
+     */
+    function walkConditionalFactor($factor);
+
+    /**
+     * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalPrimary
+     * @return string The SQL.
+     */
+    function walkConditionalPrimary($primary);
+
+    /**
+     * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ExistsExpression
+     * @return string The SQL.
+     */
+    function walkExistsExpression($existsExpr);
+
+    /**
+     * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param CollectionMemberExpression
+     * @return string The SQL.
+     */
+    function walkCollectionMemberExpression($collMemberExpr);
+
+    /**
+     * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param EmptyCollectionComparisonExpression
+     * @return string The SQL.
+     */
+    function walkEmptyCollectionComparisonExpression($emptyCollCompExpr);
+
+    /**
+     * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param NullComparisonExpression
+     * @return string The SQL.
+     */
+    function walkNullComparisonExpression($nullCompExpr);
+
+    /**
+     * Walks down an InExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InExpression
+     * @return string The SQL.
+     */
+    function walkInExpression($inExpr);
+
+    /**
+     * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InstanceOfExpression
+     * @return string The SQL.
+     */
+    function walkInstanceOfExpression($instanceOfExpr);
+
+    /**
+     * Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    function walkLiteral($literal);
+
+    /**
+     * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param BetweenExpression
+     * @return string The SQL.
+     */
+    function walkBetweenExpression($betweenExpr);
+
+    /**
+     * Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param LikeExpression
+     * @return string The SQL.
+     */
+    function walkLikeExpression($likeExpr);
+
+    /**
+     * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param StateFieldPathExpression
+     * @return string The SQL.
+     */
+    function walkStateFieldPathExpression($stateFieldPathExpression);
+
+    /**
+     * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ComparisonExpression
+     * @return string The SQL.
+     */
+    function walkComparisonExpression($compExpr);
+
+    /**
+     * Walks down an InputParameter AST node, thereby generating the appropriate SQL.
+     *
+     * @param InputParameter
+     * @return string The SQL.
+     */
+    function walkInputParameter($inputParam);
+
+    /**
+     * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ArithmeticExpression
+     * @return string The SQL.
+     */
+    function walkArithmeticExpression($arithmeticExpr);
+
+    /**
+     * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    function walkArithmeticTerm($term);
+
+    /**
+     * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    function walkStringPrimary($stringPrimary);
+
+    /**
+     * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    function walkArithmeticFactor($factor);
+
+    /**
+     * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleArithmeticExpression
+     * @return string The SQL.
+     */
+    function walkSimpleArithmeticExpression($simpleArithmeticExpr);
+
+    /**
+     * Walks down an PathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    function walkPathExpression($pathExpr);
+
+    /**
+     * Walks down an ResultVariable AST node, thereby generating the appropriate SQL.
+     *
+     * @param string $resultVariable
+     * @return string The SQL.
+     */
+    function walkResultVariable($resultVariable);
+
+    /**
+     * Gets an executor that can be used to execute the result of this walker.
+     *
+     * @return AbstractExecutor
+     */
+    function getExecutor($AST);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerAdapter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerAdapter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerAdapter.php	(revision 345)
@@ -0,0 +1,445 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * An adapter implementation of the TreeWalker interface. The methods in this class
+ * are empty. ï»¿This class exists as convenience for creating tree walkers.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+abstract class TreeWalkerAdapter implements TreeWalker
+{
+    private $_query;
+    private $_parserResult;
+    private $_queryComponents;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($query, $parserResult, array $queryComponents)
+    {
+        $this->_query = $query;
+        $this->_parserResult = $parserResult;
+        $this->_queryComponents = $queryComponents;
+    }
+
+    /**
+     * @return array
+     */
+    protected function _getQueryComponents()
+    {
+        return $this->_queryComponents;
+    }
+
+    /**
+     * Retrieve Query Instance reponsible for the current walkers execution.
+     *
+     * @return \Doctrine\ORM\Query
+     */
+    protected function _getQuery()
+    {
+        return $this->_query;
+    }
+
+    /**
+     * Retrieve ParserResult
+     *
+     * @return \Doctrine\ORM\Query\ParserResult
+     */
+    protected function _getParserResult()
+    {
+        return $this->_parserResult;
+    }
+
+    /**
+     * Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkSelectStatement(AST\SelectStatement $AST) {}
+
+    /**
+     * Walks down a SelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkSelectClause($selectClause) {}
+
+    /**
+     * Walks down a FromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFromClause($fromClause) {}
+
+    /**
+     * Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFunction($function) {}
+
+    /**
+     * Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByClause
+     * @return string The SQL.
+     */
+    public function walkOrderByClause($orderByClause) {}
+
+    /**
+     * Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByItem
+     * @return string The SQL.
+     */
+    public function walkOrderByItem($orderByItem) {}
+
+    /**
+     * Walks down a HavingClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param HavingClause
+     * @return string The SQL.
+     */
+    public function walkHavingClause($havingClause) {}
+
+    /**
+     * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
+     *
+     * @param JoinVariableDeclaration $joinVarDecl
+     * @return string The SQL.
+     */
+    public function walkJoinVariableDeclaration($joinVarDecl) {}
+
+    /**
+     * Walks down a SelectExpression AST node and generates the corresponding SQL.
+     *
+     * @param SelectExpression $selectExpression
+     * @return string The SQL.
+     */
+    public function walkSelectExpression($selectExpression) {}
+
+    /**
+     * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param QuantifiedExpression
+     * @return string The SQL.
+     */
+    public function walkQuantifiedExpression($qExpr) {}
+
+    /**
+     * Walks down a Subselect AST node, thereby generating the appropriate SQL.
+     *
+     * @param Subselect
+     * @return string The SQL.
+     */
+    public function walkSubselect($subselect) {}
+
+    /**
+     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SubselectFromClause
+     * @return string The SQL.
+     */
+    public function walkSubselectFromClause($subselectFromClause) {}
+
+    /**
+     * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectClause
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectClause($simpleSelectClause) {}
+
+    /**
+     * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectExpression($simpleSelectExpression) {}
+
+    /**
+     * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param AggregateExpression
+     * @return string The SQL.
+     */
+    public function walkAggregateExpression($aggExpression) {}
+
+    /**
+     * Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByClause
+     * @return string The SQL.
+     */
+    public function walkGroupByClause($groupByClause) {}
+
+    /**
+     * Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByItem
+     * @return string The SQL.
+     */
+    public function walkGroupByItem($groupByItem) {}
+
+    /**
+     * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateStatement
+     * @return string The SQL.
+     */
+    public function walkUpdateStatement(AST\UpdateStatement $AST) {}
+
+    /**
+     * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteStatement
+     * @return string The SQL.
+     */
+    public function walkDeleteStatement(AST\DeleteStatement $AST) {}
+
+    /**
+     * Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteClause
+     * @return string The SQL.
+     */
+    public function walkDeleteClause(AST\DeleteClause $deleteClause) {}
+
+    /**
+     * Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateClause
+     * @return string The SQL.
+     */
+    public function walkUpdateClause($updateClause) {}
+
+    /**
+     * Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateItem
+     * @return string The SQL.
+     */
+    public function walkUpdateItem($updateItem) {}
+
+    /**
+     * Walks down a WhereClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param WhereClause
+     * @return string The SQL.
+     */
+    public function walkWhereClause($whereClause) {}
+
+    /**
+     * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalExpression
+     * @return string The SQL.
+     */
+    public function walkConditionalExpression($condExpr) {}
+
+    /**
+     * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalTerm
+     * @return string The SQL.
+     */
+    public function walkConditionalTerm($condTerm) {}
+
+    /**
+     * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalFactor
+     * @return string The SQL.
+     */
+    public function walkConditionalFactor($factor) {}
+
+    /**
+     * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalPrimary
+     * @return string The SQL.
+     */
+    public function walkConditionalPrimary($primary) {}
+
+    /**
+     * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ExistsExpression
+     * @return string The SQL.
+     */
+    public function walkExistsExpression($existsExpr) {}
+
+    /**
+     * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param CollectionMemberExpression
+     * @return string The SQL.
+     */
+    public function walkCollectionMemberExpression($collMemberExpr) {}
+
+    /**
+     * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param EmptyCollectionComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) {}
+
+    /**
+     * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param NullComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkNullComparisonExpression($nullCompExpr) {}
+
+    /**
+     * Walks down an InExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InExpression
+     * @return string The SQL.
+     */
+    public function walkInExpression($inExpr) {}
+
+    /**
+     * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InstanceOfExpression
+     * @return string The SQL.
+     */
+    function walkInstanceOfExpression($instanceOfExpr) {}
+
+    /**
+     * Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkLiteral($literal) {}
+
+    /**
+     * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param BetweenExpression
+     * @return string The SQL.
+     */
+    public function walkBetweenExpression($betweenExpr) {}
+
+    /**
+     * Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param LikeExpression
+     * @return string The SQL.
+     */
+    public function walkLikeExpression($likeExpr) {}
+
+    /**
+     * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param StateFieldPathExpression
+     * @return string The SQL.
+     */
+    public function walkStateFieldPathExpression($stateFieldPathExpression) {}
+
+    /**
+     * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkComparisonExpression($compExpr) {}
+
+    /**
+     * Walks down an InputParameter AST node, thereby generating the appropriate SQL.
+     *
+     * @param InputParameter
+     * @return string The SQL.
+     */
+    public function walkInputParameter($inputParam) {}
+
+    /**
+     * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkArithmeticExpression($arithmeticExpr) {}
+
+    /**
+     * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticTerm($term) {}
+
+    /**
+     * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkStringPrimary($stringPrimary) {}
+
+    /**
+     * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticFactor($factor) {}
+
+    /**
+     * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleArithmeticExpression($simpleArithmeticExpr) {}
+
+    /**
+     * Walks down an PathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkPathExpression($pathExpr) {}
+
+    /**
+     * Walks down an ResultVariable AST node, thereby generating the appropriate SQL.
+     *
+     * @param string $resultVariable
+     * @return string The SQL.
+     */
+    public function walkResultVariable($resultVariable) {}
+
+    /**
+     * Gets an executor that can be used to execute the result of this walker.
+     *
+     * @return AbstractExecutor
+     */
+    public function getExecutor($AST) {}
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerChain.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerChain.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Query/TreeWalkerChain.php	(revision 345)
@@ -0,0 +1,664 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query;
+
+/**
+ * Represents a chain of tree walkers that modify an AST and finally emit output.
+ * Only the last walker in the chain can emit output. Any previous walkers can modify
+ * the AST to influence the final output produced by the last walker.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class TreeWalkerChain implements TreeWalker
+{
+    /** The tree walkers. */
+    private $_walkers = array();
+    /** The original Query. */
+    private $_query;
+    /** The ParserResult of the original query that was produced by the Parser. */
+    private $_parserResult;
+    /** The query components of the original query (the "symbol table") that was produced by the Parser. */
+    private $_queryComponents;
+
+    /**
+     * @inheritdoc
+     */
+    public function __construct($query, $parserResult, array $queryComponents)
+    {
+        $this->_query = $query;
+        $this->_parserResult = $parserResult;
+        $this->_queryComponents = $queryComponents;
+    }
+
+    /**
+     * Adds a tree walker to the chain.
+     *
+     * @param string $walkerClass The class of the walker to instantiate.
+     */
+    public function addTreeWalker($walkerClass)
+    {
+        $this->_walkers[] = new $walkerClass($this->_query, $this->_parserResult, $this->_queryComponents);
+    }
+
+    /**
+     * Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkSelectStatement(AST\SelectStatement $AST)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSelectStatement($AST);
+        }
+    }
+
+    /**
+     * Walks down a SelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkSelectClause($selectClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSelectClause($selectClause);
+        }
+    }
+
+    /**
+     * Walks down a FromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFromClause($fromClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkFromClause($fromClause);
+        }
+    }
+
+    /**
+     * Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
+     *
+     * @return string The SQL.
+     */
+    public function walkFunction($function)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkFunction($function);
+        }
+    }
+
+    /**
+     * Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByClause
+     * @return string The SQL.
+     */
+    public function walkOrderByClause($orderByClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkOrderByClause($orderByClause);
+        }
+    }
+
+    /**
+     * Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param OrderByItem
+     * @return string The SQL.
+     */
+    public function walkOrderByItem($orderByItem)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkOrderByItem($orderByItem);
+        }
+    }
+
+    /**
+     * Walks down a HavingClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param HavingClause
+     * @return string The SQL.
+     */
+    public function walkHavingClause($havingClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkHavingClause($havingClause);
+        }
+    }
+
+    /**
+     * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
+     *
+     * @param JoinVariableDeclaration $joinVarDecl
+     * @return string The SQL.
+     */
+    public function walkJoinVariableDeclaration($joinVarDecl)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkJoinVariableDeclaration($joinVarDecl);
+        }
+    }
+
+    /**
+     * Walks down a SelectExpression AST node and generates the corresponding SQL.
+     *
+     * @param SelectExpression $selectExpression
+     * @return string The SQL.
+     */
+    public function walkSelectExpression($selectExpression)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSelectExpression($selectExpression);
+        }
+    }
+
+    /**
+     * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param QuantifiedExpression
+     * @return string The SQL.
+     */
+    public function walkQuantifiedExpression($qExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkQuantifiedExpression($qExpr);
+        }
+    }
+
+    /**
+     * Walks down a Subselect AST node, thereby generating the appropriate SQL.
+     *
+     * @param Subselect
+     * @return string The SQL.
+     */
+    public function walkSubselect($subselect)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSubselect($subselect);
+        }
+    }
+
+    /**
+     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SubselectFromClause
+     * @return string The SQL.
+     */
+    public function walkSubselectFromClause($subselectFromClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSubselectFromClause($subselectFromClause);
+        }
+    }
+
+    /**
+     * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectClause
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectClause($simpleSelectClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSimpleSelectClause($simpleSelectClause);
+        }
+    }
+
+    /**
+     * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleSelectExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleSelectExpression($simpleSelectExpression)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSimpleSelectExpression($simpleSelectExpression);
+        }
+    }
+
+    /**
+     * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param AggregateExpression
+     * @return string The SQL.
+     */
+    public function walkAggregateExpression($aggExpression)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkAggregateExpression($aggExpression);
+        }
+    }
+
+    /**
+     * Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByClause
+     * @return string The SQL.
+     */
+    public function walkGroupByClause($groupByClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkGroupByClause($groupByClause);
+        }
+    }
+
+    /**
+     * Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param GroupByItem
+     * @return string The SQL.
+     */
+    public function walkGroupByItem($groupByItem)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkGroupByItem($groupByItem);
+        }
+    }
+
+    /**
+     * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateStatement
+     * @return string The SQL.
+     */
+    public function walkUpdateStatement(AST\UpdateStatement $AST)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkUpdateStatement($AST);
+        }
+    }
+
+    /**
+     * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteStatement
+     * @return string The SQL.
+     */
+    public function walkDeleteStatement(AST\DeleteStatement $AST)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkDeleteStatement($AST);
+        }
+    }
+
+    /**
+     * Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param DeleteClause
+     * @return string The SQL.
+     */
+    public function walkDeleteClause(AST\DeleteClause $deleteClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkDeleteClause($deleteClause);
+        }
+    }
+
+    /**
+     * Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateClause
+     * @return string The SQL.
+     */
+    public function walkUpdateClause($updateClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkUpdateClause($updateClause);
+        }
+    }
+
+    /**
+     * Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
+     *
+     * @param UpdateItem
+     * @return string The SQL.
+     */
+    public function walkUpdateItem($updateItem)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkUpdateItem($updateItem);
+        }
+    }
+
+    /**
+     * Walks down a WhereClause AST node, thereby generating the appropriate SQL.
+     *
+     * @param WhereClause
+     * @return string The SQL.
+     */
+    public function walkWhereClause($whereClause)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkWhereClause($whereClause);
+        }
+    }
+
+    /**
+     * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalExpression
+     * @return string The SQL.
+     */
+    public function walkConditionalExpression($condExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkConditionalExpression($condExpr);
+        }
+    }
+
+    /**
+     * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalTerm
+     * @return string The SQL.
+     */
+    public function walkConditionalTerm($condTerm)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkConditionalTerm($condTerm);
+        }
+    }
+
+    /**
+     * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalFactor
+     * @return string The SQL.
+     */
+    public function walkConditionalFactor($factor)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkConditionalFactor($factor);
+        }
+    }
+
+    /**
+     * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL.
+     *
+     * @param ConditionalPrimary
+     * @return string The SQL.
+     */
+    public function walkConditionalPrimary($condPrimary)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkConditionalPrimary($condPrimary);
+        }
+    }
+
+    /**
+     * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ExistsExpression
+     * @return string The SQL.
+     */
+    public function walkExistsExpression($existsExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkExistsExpression($existsExpr);
+        }
+    }
+
+    /**
+     * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param CollectionMemberExpression
+     * @return string The SQL.
+     */
+    public function walkCollectionMemberExpression($collMemberExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkCollectionMemberExpression($collMemberExpr);
+        }
+    }
+
+    /**
+     * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param EmptyCollectionComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkEmptyCollectionComparisonExpression($emptyCollCompExpr);
+        }
+    }
+
+    /**
+     * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param NullComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkNullComparisonExpression($nullCompExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkNullComparisonExpression($nullCompExpr);
+        }
+    }
+
+    /**
+     * Walks down an InExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InExpression
+     * @return string The SQL.
+     */
+    public function walkInExpression($inExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkInExpression($inExpr);
+        }
+    }
+
+    /**
+     * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param InstanceOfExpression
+     * @return string The SQL.
+     */
+    function walkInstanceOfExpression($instanceOfExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkInstanceOfExpression($instanceOfExpr);
+        }
+    }
+
+    /**
+     * Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkLiteral($literal)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkLiteral($literal);
+        }
+    }
+
+    /**
+     * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param BetweenExpression
+     * @return string The SQL.
+     */
+    public function walkBetweenExpression($betweenExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkBetweenExpression($betweenExpr);
+        }
+    }
+
+    /**
+     * Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param LikeExpression
+     * @return string The SQL.
+     */
+    public function walkLikeExpression($likeExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkLikeExpression($likeExpr);
+        }
+    }
+
+    /**
+     * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param StateFieldPathExpression
+     * @return string The SQL.
+     */
+    public function walkStateFieldPathExpression($stateFieldPathExpression)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkStateFieldPathExpression($stateFieldPathExpression);
+        }
+    }
+
+    /**
+     * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ComparisonExpression
+     * @return string The SQL.
+     */
+    public function walkComparisonExpression($compExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkComparisonExpression($compExpr);
+        }
+    }
+
+    /**
+     * Walks down an InputParameter AST node, thereby generating the appropriate SQL.
+     *
+     * @param InputParameter
+     * @return string The SQL.
+     */
+    public function walkInputParameter($inputParam)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkInputParameter($inputParam);
+        }
+    }
+
+    /**
+     * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param ArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkArithmeticExpression($arithmeticExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkArithmeticExpression($arithmeticExpr);
+        }
+    }
+
+    /**
+     * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticTerm($term)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkArithmeticTerm($term);
+        }
+    }
+
+    /**
+     * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkStringPrimary($stringPrimary)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkStringPrimary($stringPrimary);
+        }
+    }
+
+    /**
+     * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkArithmeticFactor($factor)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkArithmeticFactor($factor);
+        }
+    }
+
+    /**
+     * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param SimpleArithmeticExpression
+     * @return string The SQL.
+     */
+    public function walkSimpleArithmeticExpression($simpleArithmeticExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkSimpleArithmeticExpression($simpleArithmeticExpr);
+        }
+    }
+
+    /**
+     * Walks down an PathExpression AST node, thereby generating the appropriate SQL.
+     *
+     * @param mixed
+     * @return string The SQL.
+     */
+    public function walkPathExpression($pathExpr)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkPathExpression($pathExpr);
+        }
+    }
+
+    /**
+     * Walks down an ResultVariable AST node, thereby generating the appropriate SQL.
+     *
+     * @param string $resultVariable
+     * @return string The SQL.
+     */
+    public function walkResultVariable($resultVariable)
+    {
+        foreach ($this->_walkers as $walker) {
+            $walker->walkResultVariable($resultVariable);
+        }
+    }
+
+    /**
+     * Gets an executor that can be used to execute the result of this walker.
+     *
+     * @return AbstractExecutor
+     */
+    public function getExecutor($AST)
+    {}
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/QueryBuilder.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/QueryBuilder.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/QueryBuilder.php	(revision 345)
@@ -0,0 +1,1115 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\ORM\Query\Expr;
+
+/**
+ * This class is responsible for building DQL query strings via an object oriented
+ * PHP interface.
+ *
+ * @since 2.0
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class QueryBuilder
+{
+    /* The query types. */
+    const SELECT = 0;
+    const DELETE = 1;
+    const UPDATE = 2;
+
+    /** The builder states. */
+    const STATE_DIRTY = 0;
+    const STATE_CLEAN = 1;
+
+    /**
+     * @var EntityManager The EntityManager used by this QueryBuilder.
+     */
+    private $_em;
+
+    /**
+     * @var array The array of DQL parts collected.
+     */
+    private $_dqlParts = array(
+        'distinct' => false,
+        'select'  => array(),
+        'from'    => array(),
+        'join'    => array(),
+        'set'     => array(),
+        'where'   => null,
+        'groupBy' => array(),
+        'having'  => null,
+        'orderBy' => array()
+    );
+
+    /**
+     * @var integer The type of query this is. Can be select, update or delete.
+     */
+    private $_type = self::SELECT;
+
+    /**
+     * @var integer The state of the query object. Can be dirty or clean.
+     */
+    private $_state = self::STATE_CLEAN;
+
+    /**
+     * @var string The complete DQL string for this query.
+     */
+    private $_dql;
+
+    /**
+     * @var array The query parameters.
+     */
+    private $_params = array();
+
+    /**
+     * @var array The parameter type map of this query.
+     */
+    private $_paramTypes = array();
+
+    /**
+     * @var integer The index of the first result to retrieve.
+     */
+    private $_firstResult = null;
+
+    /**
+     * @var integer The maximum number of results to retrieve.
+     */
+    private $_maxResults = null;
+
+    /**
+     * Initializes a new <tt>QueryBuilder</tt> that uses the given <tt>EntityManager</tt>.
+     *
+     * @param EntityManager $em The EntityManager to use.
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em = $em;
+    }
+
+    /**
+     * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
+     * This producer method is intended for convenient inline usage. Example:
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where($qb->expr()->eq('u.id', 1));
+     * </code>
+     *
+     * For more complex expression construction, consider storing the expression
+     * builder object in a local variable.
+     *
+     * @return Query\Expr
+     */
+    public function expr()
+    {
+        return $this->_em->getExpressionBuilder();
+    }
+
+    /**
+     * Get the type of the currently built query.
+     *
+     * @return integer
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * Get the associated EntityManager for this query builder.
+     *
+     * @return EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * Get the state of this query builder instance.
+     *
+     * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
+     */
+    public function getState()
+    {
+        return $this->_state;
+    }
+
+    /**
+     * Get the complete DQL string formed by the current specifications of this QueryBuilder.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *     echo $qb->getDql(); // SELECT u FROM User u
+     * </code>
+     *
+     * @return string The DQL query string.
+     */
+    public function getDQL()
+    {
+        if ($this->_dql !== null && $this->_state === self::STATE_CLEAN) {
+            return $this->_dql;
+        }
+
+        $dql = '';
+
+        switch ($this->_type) {
+            case self::DELETE:
+                $dql = $this->_getDQLForDelete();
+                break;
+
+            case self::UPDATE:
+                $dql = $this->_getDQLForUpdate();
+                break;
+
+            case self::SELECT:
+            default:
+                $dql = $this->_getDQLForSelect();
+                break;
+        }
+
+        $this->_state = self::STATE_CLEAN;
+        $this->_dql = $dql;
+
+        return $dql;
+    }
+
+    /**
+     * Constructs a Query instance from the current specifications of the builder.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u');
+     *     $q = $qb->getQuery();
+     *     $results = $q->execute();
+     * </code>
+     *
+     * @return Query
+     */
+    public function getQuery()
+    {
+        return $this->_em->createQuery($this->getDQL())
+                ->setParameters($this->_params, $this->_paramTypes)
+                ->setFirstResult($this->_firstResult)
+                ->setMaxResults($this->_maxResults);
+    }
+
+    /**
+     * Gets the FIRST root alias of the query. This is the first entity alias involved
+     * in the construction of the query.
+     *
+     * <code>
+     * $qb = $em->createQueryBuilder()
+     * ->select('u')
+     * ->from('User', 'u');
+     *
+     * echo $qb->getRootAlias(); // u
+     * </code>
+     *
+     * @deprecated Please use $qb->getRootAliases() instead.
+     * @return string $rootAlias
+     */
+    public function getRootAlias()
+    {
+        $aliases = $this->getRootAliases();
+        return $aliases[0];
+    }
+
+    /**
+     * Gets the root aliases of the query. This is the entity aliases involved
+     * in the construction of the query.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u');
+     *
+     *     $qb->getRootAliases(); // array('u')
+     * </code>
+     *
+     * @return array $rootAliases
+     */
+    public function getRootAliases()
+    {
+        $aliases = array();
+
+        foreach ($this->_dqlParts['from'] as &$fromClause) {
+            if (is_string($fromClause)) {
+                $spacePos = strrpos($fromClause, ' ');
+                $from     = substr($fromClause, 0, $spacePos);
+                $alias    = substr($fromClause, $spacePos + 1);
+
+                $fromClause = new Query\Expr\From($from, $alias);
+            }
+
+            $aliases[] = $fromClause->getAlias();
+        }
+
+        return $aliases;
+    }
+
+    /**
+     * Gets the root entities of the query. This is the entity aliases involved
+     * in the construction of the query.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u');
+     *
+     *     $qb->getRootEntities(); // array('User')
+     * </code>
+     *
+     * @return array $rootEntities
+     */
+    public function getRootEntities()
+    {
+        $entities = array();
+
+        foreach ($this->_dqlParts['from'] as &$fromClause) {
+            if (is_string($fromClause)) {
+                $spacePos = strrpos($fromClause, ' ');
+                $from     = substr($fromClause, 0, $spacePos);
+                $alias    = substr($fromClause, $spacePos + 1);
+
+                $fromClause = new Query\Expr\From($from, $alias);
+            }
+
+            $entities[] = $fromClause->getFrom();
+        }
+
+        return $entities;
+    }
+
+    /**
+     * Sets a query parameter for the query being constructed.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where('u.id = :user_id')
+     *         ->setParameter('user_id', 1);
+     * </code>
+     *
+     * @param string|integer $key The parameter position or name.
+     * @param mixed $value The parameter value.
+     * @param string|null $type PDO::PARAM_* or \Doctrine\DBAL\Types\Type::* constant
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setParameter($key, $value, $type = null)
+    {
+        $key = trim($key, ':');
+
+        if ($type === null) {
+            $type = Query\ParameterTypeInferer::inferType($value);
+        }
+
+        $this->_paramTypes[$key] = $type;
+        $this->_params[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets a collection of query parameters for the query being constructed.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where('u.id = :user_id1 OR u.id = :user_id2')
+     *         ->setParameters(array(
+     *             'user_id1' => 1,
+     *             'user_id2' => 2
+              ));
+     * </code>
+     *
+     * @param array $params The query parameters to set.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setParameters(array $params, array $types = array())
+    {
+        foreach ($params as $key => $value) {
+            $this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Gets all defined query parameters for the query being constructed.
+     *
+     * @return array The currently defined query parameters.
+     */
+    public function getParameters()
+    {
+        return $this->_params;
+    }
+
+    /**
+     * Gets a (previously set) query parameter of the query being constructed.
+     *
+     * @param mixed $key The key (index or name) of the bound parameter.
+     * @return mixed The value of the bound parameter.
+     */
+    public function getParameter($key)
+    {
+        return isset($this->_params[$key]) ? $this->_params[$key] : null;
+    }
+
+    /**
+     * Sets the position of the first result to retrieve (the "offset").
+     *
+     * @param integer $firstResult The first result to return.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setFirstResult($firstResult)
+    {
+        $this->_firstResult = $firstResult;
+
+        return $this;
+    }
+
+    /**
+     * Gets the position of the first result the query object was set to retrieve (the "offset").
+     * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
+     *
+     * @return integer The position of the first result.
+     */
+    public function getFirstResult()
+    {
+        return $this->_firstResult;
+    }
+
+    /**
+     * Sets the maximum number of results to retrieve (the "limit").
+     *
+     * @param integer $maxResults The maximum number of results to retrieve.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function setMaxResults($maxResults)
+    {
+        $this->_maxResults = $maxResults;
+
+        return $this;
+    }
+
+    /**
+     * Gets the maximum number of results the query object was set to retrieve (the "limit").
+     * Returns NULL if {@link setMaxResults} was not applied to this query builder.
+     *
+     * @return integer Maximum number of results.
+     */
+    public function getMaxResults()
+    {
+        return $this->_maxResults;
+    }
+
+    /**
+     * Either appends to or replaces a single, generic query part.
+     *
+     * The available parts are: 'select', 'from', 'join', 'set', 'where',
+     * 'groupBy', 'having' and 'orderBy'.
+     *
+     * @param string $dqlPartName
+     * @param string $dqlPart
+     * @param string $append
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function add($dqlPartName, $dqlPart, $append = false)
+    {
+        $isMultiple = is_array($this->_dqlParts[$dqlPartName]);
+
+        // This is introduced for backwards compatibility reasons.
+        // TODO: Remove for 3.0
+        if ($dqlPartName == 'join') {
+            $newDqlPart = array();
+            foreach ($dqlPart AS $k => $v) {
+                if (is_numeric($k)) {
+                    $newDqlPart[$this->getRootAlias()] = $v;
+                } else {
+                    $newDqlPart[$k] = $v;
+                }
+            }
+            $dqlPart = $newDqlPart;
+        }
+
+        if ($append && $isMultiple) {
+            if (is_array($dqlPart)) {
+                $key = key($dqlPart);
+
+                $this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key];
+            } else {
+                $this->_dqlParts[$dqlPartName][] = $dqlPart;
+            }
+        } else {
+            $this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart;
+        }
+
+        $this->_state = self::STATE_DIRTY;
+
+        return $this;
+    }
+
+    /**
+     * Specifies an item that is to be returned in the query result.
+     * Replaces any previously specified selections, if any.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u', 'p')
+     *         ->from('User', 'u')
+     *         ->leftJoin('u.Phonenumbers', 'p');
+     * </code>
+     *
+     * @param mixed $select The selection expressions.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function select($select = null)
+    {
+        $this->_type = self::SELECT;
+
+        if (empty($select)) {
+            return $this;
+        }
+
+        $selects = is_array($select) ? $select : func_get_args();
+
+        return $this->add('select', new Expr\Select($selects), false);
+    }
+
+    /**
+     * Add a DISTINCT flag to this query.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->distinct()
+     *         ->from('User', 'u');
+     * </code>
+     *
+     * @param bool
+     * @return QueryBuilder
+     */
+    public function distinct($flag = true)
+    {
+        $this->_dqlParts['distinct'] = (bool) $flag;
+        return $this;
+    }
+
+    /**
+     * Adds an item that is to be returned in the query result.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->addSelect('p')
+     *         ->from('User', 'u')
+     *         ->leftJoin('u.Phonenumbers', 'p');
+     * </code>
+     *
+     * @param mixed $select The selection expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addSelect($select = null)
+    {
+        $this->_type = self::SELECT;
+
+        if (empty($select)) {
+            return $this;
+        }
+
+        $selects = is_array($select) ? $select : func_get_args();
+
+        return $this->add('select', new Expr\Select($selects), true);
+    }
+
+    /**
+     * Turns the query being built into a bulk delete query that ranges over
+     * a certain entity type.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->delete('User', 'u')
+     *         ->where('u.id = :user_id');
+     *         ->setParameter('user_id', 1);
+     * </code>
+     *
+     * @param string $delete The class/type whose instances are subject to the deletion.
+     * @param string $alias The class/type alias used in the constructed query.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function delete($delete = null, $alias = null)
+    {
+        $this->_type = self::DELETE;
+
+        if ( ! $delete) {
+            return $this;
+        }
+
+        return $this->add('from', new Expr\From($delete, $alias));
+    }
+
+    /**
+     * Turns the query being built into a bulk update query that ranges over
+     * a certain entity type.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->update('User', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where('u.id = ?');
+     * </code>
+     *
+     * @param string $update The class/type whose instances are subject to the update.
+     * @param string $alias The class/type alias used in the constructed query.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function update($update = null, $alias = null)
+    {
+        $this->_type = self::UPDATE;
+
+        if ( ! $update) {
+            return $this;
+        }
+
+        return $this->add('from', new Expr\From($update, $alias));
+    }
+
+    /**
+     * Create and add a query root corresponding to the entity identified by the given alias,
+     * forming a cartesian product with any existing query roots.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     * </code>
+     *
+     * @param string $from   The class name.
+     * @param string $alias  The alias of the class.
+     * @param string $indexBy The index for the from.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function from($from, $alias, $indexBy = null)
+    {
+        return $this->add('from', new Expr\From($from, $alias, $indexBy), true);
+    }
+
+    /**
+     * Creates and adds a join over an entity association to the query.
+     *
+     * The entities in the joined association will be fetched as part of the query
+     * result if the alias used for the joined association is placed in the select
+     * expressions.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->join('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $join The relationship to join
+     * @param string $alias The alias of the join
+     * @param string $conditionType The condition type constant. Either ON or WITH.
+     * @param string $condition The condition for the join
+     * @param string $indexBy The index for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function join($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
+    {
+        return $this->innerJoin($join, $alias, $conditionType, $condition, $indexBy);
+    }
+
+    /**
+     * Creates and adds a join over an entity association to the query.
+     *
+     * The entities in the joined association will be fetched as part of the query
+     * result if the alias used for the joined association is placed in the select
+     * expressions.
+     *
+     *     [php]
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->innerJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
+     *
+     * @param string $join The relationship to join
+     * @param string $alias The alias of the join
+     * @param string $conditionType The condition type constant. Either ON or WITH.
+     * @param string $condition The condition for the join
+     * @param string $indexBy The index for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function innerJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
+    {
+        $rootAlias = substr($join, 0, strpos($join, '.'));
+
+        if ( ! in_array($rootAlias, $this->getRootAliases())) {
+            $rootAlias = $this->getRootAlias();
+        }
+
+        $join = new Expr\Join(
+            Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition, $indexBy
+        );
+
+        return $this->add('join', array($rootAlias => $join), true);
+    }
+
+    /**
+     * Creates and adds a left join over an entity association to the query.
+     *
+     * The entities in the joined association will be fetched as part of the query
+     * result if the alias used for the joined association is placed in the select
+     * expressions.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->leftJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
+     * </code>
+     *
+     * @param string $join The relationship to join
+     * @param string $alias The alias of the join
+     * @param string $conditionType The condition type constant. Either ON or WITH.
+     * @param string $condition The condition for the join
+     * @param string $indexBy The index for the join
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
+    {
+        $rootAlias = substr($join, 0, strpos($join, '.'));
+
+        if ( ! in_array($rootAlias, $this->getRootAliases())) {
+            $rootAlias = $this->getRootAlias();
+        }
+
+        $join = new Expr\Join(
+            Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition, $indexBy
+        );
+
+        return $this->add('join', array($rootAlias => $join), true);
+    }
+
+    /**
+     * Sets a new value for a field in a bulk update query.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->update('User', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where('u.id = ?');
+     * </code>
+     *
+     * @param string $key The key/field to set.
+     * @param string $value The value, expression, placeholder, etc.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function set($key, $value)
+    {
+        return $this->add('set', new Expr\Comparison($key, Expr\Comparison::EQ, $value), true);
+    }
+
+    /**
+     * Specifies one or more restrictions to the query result.
+     * Replaces any previously specified restrictions, if any.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where('u.id = ?');
+     *
+     *     // You can optionally programatically build and/or expressions
+     *     $qb = $em->createQueryBuilder();
+     *
+     *     $or = $qb->expr()->orx();
+     *     $or->add($qb->expr()->eq('u.id', 1));
+     *     $or->add($qb->expr()->eq('u.id', 2));
+     *
+     *     $qb->update('User', 'u')
+     *         ->set('u.password', md5('password'))
+     *         ->where($or);
+     * </code>
+     *
+     * @param mixed $predicates The restriction predicates.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function where($predicates)
+    {
+        if ( ! (func_num_args() == 1 && $predicates instanceof Expr\Composite)) {
+            $predicates = new Expr\Andx(func_get_args());
+        }
+
+        return $this->add('where', $predicates);
+    }
+
+    /**
+     * Adds one or more restrictions to the query results, forming a logical
+     * conjunction with any previously specified restrictions.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where('u.username LIKE ?')
+     *         ->andWhere('u.is_active = 1');
+     * </code>
+     *
+     * @param mixed $where The query restrictions.
+     * @return QueryBuilder This QueryBuilder instance.
+     * @see where()
+     */
+    public function andWhere($where)
+    {
+        $where = $this->getDQLPart('where');
+        $args = func_get_args();
+
+        if ($where instanceof Expr\Andx) {
+            $where->addMultiple($args);
+        } else {
+            array_unshift($args, $where);
+            $where = new Expr\Andx($args);
+        }
+
+        return $this->add('where', $where, true);
+    }
+
+    /**
+     * Adds one or more restrictions to the query results, forming a logical
+     * disjunction with any previously specified restrictions.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->where('u.id = 1')
+     *         ->orWhere('u.id = 2');
+     * </code>
+     *
+     * @param mixed $where The WHERE statement
+     * @return QueryBuilder $qb
+     * @see where()
+     */
+    public function orWhere($where)
+    {
+        $where = $this->getDqlPart('where');
+        $args = func_get_args();
+
+        if ($where instanceof Expr\Orx) {
+            $where->addMultiple($args);
+        } else {
+            array_unshift($args, $where);
+            $where = new Expr\Orx($args);
+        }
+
+        return $this->add('where', $where, true);
+    }
+
+    /**
+     * Specifies a grouping over the results of the query.
+     * Replaces any previously specified groupings, if any.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->groupBy('u.id');
+     * </code>
+     *
+     * @param string $groupBy The grouping expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function groupBy($groupBy)
+    {
+        return $this->add('groupBy', new Expr\GroupBy(func_get_args()));
+    }
+
+
+    /**
+     * Adds a grouping expression to the query.
+     *
+     * <code>
+     *     $qb = $em->createQueryBuilder()
+     *         ->select('u')
+     *         ->from('User', 'u')
+     *         ->groupBy('u.lastLogin');
+     *         ->addGroupBy('u.createdAt')
+     * </code>
+     *
+     * @param string $groupBy The grouping expression.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addGroupBy($groupBy)
+    {
+        return $this->add('groupBy', new Expr\GroupBy(func_get_args()), true);
+    }
+
+    /**
+     * Specifies a restriction over the groups of the query.
+     * Replaces any previous having restrictions, if any.
+     *
+     * @param mixed $having The restriction over the groups.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function having($having)
+    {
+        if ( ! (func_num_args() == 1 && ($having instanceof Expr\Andx || $having instanceof Expr\Orx))) {
+            $having = new Expr\Andx(func_get_args());
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Adds a restriction over the groups of the query, forming a logical
+     * conjunction with any existing having restrictions.
+     *
+     * @param mixed $having The restriction to append.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function andHaving($having)
+    {
+        $having = $this->getDqlPart('having');
+        $args = func_get_args();
+
+        if ($having instanceof Expr\Andx) {
+            $having->addMultiple($args);
+        } else {
+            array_unshift($args, $having);
+            $having = new Expr\Andx($args);
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Adds a restriction over the groups of the query, forming a logical
+     * disjunction with any existing having restrictions.
+     *
+     * @param mixed $having The restriction to add.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function orHaving($having)
+    {
+        $having = $this->getDqlPart('having');
+        $args = func_get_args();
+
+        if ($having instanceof Expr\Orx) {
+            $having->addMultiple($args);
+        } else {
+            array_unshift($args, $having);
+            $having = new Expr\Orx($args);
+        }
+
+        return $this->add('having', $having);
+    }
+
+    /**
+     * Specifies an ordering for the query results.
+     * Replaces any previously specified orderings, if any.
+     *
+     * @param string $sort The ordering expression.
+     * @param string $order The ordering direction.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function orderBy($sort, $order = null)
+    {
+        return $this->add('orderBy',  $sort instanceof Expr\OrderBy ? $sort
+                : new Expr\OrderBy($sort, $order));
+    }
+
+    /**
+     * Adds an ordering to the query results.
+     *
+     * @param string $sort The ordering expression.
+     * @param string $order The ordering direction.
+     * @return QueryBuilder This QueryBuilder instance.
+     */
+    public function addOrderBy($sort, $order = null)
+    {
+        return $this->add('orderBy', new Expr\OrderBy($sort, $order), true);
+    }
+
+    /**
+     * Get a query part by its name.
+     *
+     * @param string $queryPartName
+     * @return mixed $queryPart
+     * @todo Rename: getQueryPart (or remove?)
+     */
+    public function getDQLPart($queryPartName)
+    {
+        return $this->_dqlParts[$queryPartName];
+    }
+
+    /**
+     * Get all query parts.
+     *
+     * @return array $dqlParts
+     * @todo Rename: getQueryParts (or remove?)
+     */
+    public function getDQLParts()
+    {
+        return $this->_dqlParts;
+    }
+
+    private function _getDQLForDelete()
+    {
+         return 'DELETE'
+              . $this->_getReducedDQLQueryPart('from', array('pre' => ' ', 'separator' => ', '))
+              . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE '))
+              . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '));
+    }
+
+    private function _getDQLForUpdate()
+    {
+         return 'UPDATE'
+              . $this->_getReducedDQLQueryPart('from', array('pre' => ' ', 'separator' => ', '))
+              . $this->_getReducedDQLQueryPart('set', array('pre' => ' SET ', 'separator' => ', '))
+              . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE '))
+              . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '));
+    }
+
+    private function _getDQLForSelect()
+    {
+        $dql = 'SELECT'
+              . ($this->_dqlParts['distinct']===true ? ' DISTINCT' : '')
+              . $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', '));
+
+        $fromParts   = $this->getDQLPart('from');
+        $joinParts   = $this->getDQLPart('join');
+        $fromClauses = array();
+
+        // Loop through all FROM clauses
+        if ( ! empty($fromParts)) {
+            $dql .= ' FROM ';
+
+            foreach ($fromParts as $from) {
+                $fromClause = (string) $from;
+
+                if ($from instanceof Expr\From && isset($joinParts[$from->getAlias()])) {
+                    foreach ($joinParts[$from->getAlias()] as $join) {
+                        $fromClause .= ' ' . ((string) $join);
+                    }
+                }
+
+                $fromClauses[] = $fromClause;
+            }
+        }
+
+        $dql .= implode(', ', $fromClauses)
+              . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE '))
+              . $this->_getReducedDQLQueryPart('groupBy', array('pre' => ' GROUP BY ', 'separator' => ', '))
+              . $this->_getReducedDQLQueryPart('having', array('pre' => ' HAVING '))
+              . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '));
+
+        return $dql;
+    }
+
+    private function _getReducedDQLQueryPart($queryPartName, $options = array())
+    {
+        $queryPart = $this->getDQLPart($queryPartName);
+
+        if (empty($queryPart)) {
+            return (isset($options['empty']) ? $options['empty'] : '');
+        }
+
+        return (isset($options['pre']) ? $options['pre'] : '')
+             . (is_array($queryPart) ? implode($options['separator'], $queryPart) : $queryPart)
+             . (isset($options['post']) ? $options['post'] : '');
+    }
+
+    /**
+     * Reset DQL parts
+     *
+     * @param array $parts
+     * @return QueryBuilder
+     */
+    public function resetDQLParts($parts = null)
+    {
+        if (is_null($parts)) {
+            $parts = array_keys($this->_dqlParts);
+        }
+        foreach ($parts as $part) {
+            $this->resetDQLPart($part);
+        }
+        return $this;
+    }
+
+    /**
+     * Reset single DQL part
+     *
+     * @param string $part
+     * @return QueryBuilder;
+     */
+    public function resetDQLPart($part)
+    {
+        if (is_array($this->_dqlParts[$part])) {
+            $this->_dqlParts[$part] = array();
+        } else {
+            $this->_dqlParts[$part] = null;
+        }
+        $this->_state = self::STATE_DIRTY;
+        return $this;
+    }
+
+    /**
+     * Gets a string representation of this QueryBuilder which corresponds to
+     * the final DQL query being constructed.
+     *
+     * @return string The string representation of this QueryBuilder.
+     */
+    public function __toString()
+    {
+        return $this->getDQL();
+    }
+
+    /**
+     * Deep clone of all expression objects in the DQL parts.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        foreach ($this->_dqlParts AS $part => $elements) {
+            if (is_array($this->_dqlParts[$part])) {
+                foreach ($this->_dqlParts[$part] AS $idx => $element) {
+                    if (is_object($element)) {
+                        $this->_dqlParts[$part][$idx] = clone $element;
+                    }
+                }
+            } else if (\is_object($elements)) {
+                $this->_dqlParts[$part] = clone $elements;
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php	(revision 345)
@@ -0,0 +1,104 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\Common\Cache;
+
+/**
+ * Command to clear the metadata cache of the various cache drivers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class MetadataCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:clear-cache:metadata')
+        ->setDescription('Clear all metadata cache of the various cache drivers.')
+        ->setDefinition(array(
+            new InputOption(
+                'flush', null, InputOption::VALUE_NONE,
+                'If defined, cache entries will be flushed instead of deleted/invalidated.'
+            )
+        ));
+
+        $fullName = $this->getName();
+        $this->setHelp(<<<EOT
+The <info>$fullName</info> command is meant to clear the metadata cache of associated Entity Manager.
+It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
+instance completely.
+
+The execution type differ on how you execute the command.
+If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
+
+<info>$fullName</info>
+
+Alternatively, if you want to flush the cache provider using this command:
+
+<info>$fullName --flush</info>
+
+Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
+because of a limitation of its execution nature.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+        $cacheDriver = $em->getConfiguration()->getMetadataCacheImpl();
+
+        if ( ! $cacheDriver) {
+            throw new \InvalidArgumentException('No Metadata cache driver is configured on given EntityManager.');
+        }
+
+        if ($cacheDriver instanceof Cache\ApcCache) {
+            throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
+        }
+
+        $output->write('Clearing ALL Metadata cache entries' . PHP_EOL);
+
+        $result  = $cacheDriver->deleteAll();
+        $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
+
+        if (true === $input->getOption('flush')) {
+            $result  = $cacheDriver->flushAll();
+            $message = ($result) ? 'Successfully flushed cache entries.' : $message;
+        }
+
+        $output->write($message . PHP_EOL);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php	(revision 345)
@@ -0,0 +1,104 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\Common\Cache;
+
+/**
+ * Command to clear the query cache of the various cache drivers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class QueryCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:clear-cache:query')
+        ->setDescription('Clear all query cache of the various cache drivers.')
+        ->setDefinition(array(
+            new InputOption(
+                'flush', null, InputOption::VALUE_NONE,
+                'If defined, cache entries will be flushed instead of deleted/invalidated.'
+            )
+        ));
+
+        $fullName = $this->getName();
+        $this->setHelp(<<<EOT
+The <info>$fullName</info> command is meant to clear the query cache of associated Entity Manager.
+It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
+instance completely.
+
+The execution type differ on how you execute the command.
+If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
+
+<info>$fullName</info>
+
+Alternatively, if you want to flush the cache provider using this command:
+
+<info>$fullName --flush</info>
+
+Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
+because of a limitation of its execution nature.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+        $cacheDriver = $em->getConfiguration()->getQueryCacheImpl();
+
+        if ( ! $cacheDriver) {
+            throw new \InvalidArgumentException('No Query cache driver is configured on given EntityManager.');
+        }
+
+        if ($cacheDriver instanceof Cache\ApcCache) {
+            throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
+        }
+
+        $output->write('Clearing ALL Query cache entries' . PHP_EOL);
+
+        $result  = $cacheDriver->deleteAll();
+        $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
+
+        if (true === $input->getOption('flush')) {
+            $result  = $cacheDriver->flushAll();
+            $message = ($result) ? 'Successfully flushed cache entries.' : $message;
+        }
+
+        $output->write($message . PHP_EOL);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php	(revision 345)
@@ -0,0 +1,104 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\Common\Cache;
+
+/**
+ * Command to clear the result cache of the various cache drivers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ResultCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:clear-cache:result')
+        ->setDescription('Clear all result cache of the various cache drivers.')
+        ->setDefinition(array(
+            new InputOption(
+                'flush', null, InputOption::VALUE_NONE,
+                'If defined, cache entries will be flushed instead of deleted/invalidated.'
+            )
+        ));
+
+        $fullName = $this->getName();
+        $this->setHelp(<<<EOT
+The <info>$fullName</info> command is meant to clear the result cache of associated Entity Manager.
+It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
+instance completely.
+
+The execution type differ on how you execute the command.
+If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
+
+<info>$fullName</info>
+
+Alternatively, if you want to flush the cache provider using this command:
+
+<info>$fullName --flush</info>
+
+Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
+because of a limitation of its execution nature.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+        $cacheDriver = $em->getConfiguration()->getResultCacheImpl();
+
+        if ( ! $cacheDriver) {
+            throw new \InvalidArgumentException('No Result cache driver is configured on given EntityManager.');
+        }
+
+        if ($cacheDriver instanceof Cache\ApcCache) {
+            throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
+        }
+
+        $output->write('Clearing ALL Result cache entries' . PHP_EOL);
+
+        $result  = $cacheDriver->deleteAll();
+        $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
+
+        if (true === $input->getOption('flush')) {
+            $result  = $cacheDriver->flushAll();
+            $message = ($result) ? 'Successfully flushed cache entries.' : $message;
+        }
+
+        $output->write($message . PHP_EOL);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php	(revision 345)
@@ -0,0 +1,223 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\ORM\Tools\Export\ClassMetadataExporter,
+    Doctrine\ORM\Tools\ConvertDoctrine1Schema,
+    Doctrine\ORM\Tools\EntityGenerator;
+
+/**
+ * Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConvertDoctrine1SchemaCommand extends Console\Command\Command
+{
+    /**
+     * @var EntityGenerator
+     */
+    private $entityGenerator = null;
+
+    /**
+     * @var ClassMetadataExporter
+     */
+    private $metadataExporter = null;
+
+    /**
+     * @return EntityGenerator
+     */
+    public function getEntityGenerator()
+    {
+        if ($this->entityGenerator == null) {
+            $this->entityGenerator = new EntityGenerator();
+        }
+
+        return $this->entityGenerator;
+    }
+
+    /**
+     * @param EntityGenerator $entityGenerator
+     */
+    public function setEntityGenerator(EntityGenerator $entityGenerator)
+    {
+        $this->entityGenerator = $entityGenerator;
+    }
+
+    /**
+     * @return ClassMetadataExporter
+     */
+    public function getMetadataExporter()
+    {
+        if ($this->metadataExporter == null) {
+            $this->metadataExporter = new ClassMetadataExporter();
+        }
+
+        return $this->metadataExporter;
+    }
+
+    /**
+     * @param ClassMetadataExporter $metadataExporter
+     */
+    public function setMetadataExporter(ClassMetadataExporter $metadataExporter)
+    {
+        $this->metadataExporter = $metadataExporter;
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:convert-d1-schema')
+        ->setDescription('Converts Doctrine 1.X schema into a Doctrine 2.X schema.')
+        ->setDefinition(array(
+            new InputArgument(
+                'from-path', InputArgument::REQUIRED, 'The path of Doctrine 1.X schema information.'
+            ),
+            new InputArgument(
+                'to-type', InputArgument::REQUIRED, 'The destination Doctrine 2.X mapping type.'
+            ),
+            new InputArgument(
+                'dest-path', InputArgument::REQUIRED,
+                'The path to generate your Doctrine 2.X mapping information.'
+            ),
+            new InputOption(
+                'from', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'Optional paths of Doctrine 1.X schema information.',
+                array()
+            ),
+            new InputOption(
+                'extend', null, InputOption::VALUE_OPTIONAL,
+                'Defines a base class to be extended by generated entity classes.'
+            ),
+            new InputOption(
+                'num-spaces', null, InputOption::VALUE_OPTIONAL,
+                'Defines the number of indentation spaces', 4
+            )
+        ))
+        ->setHelp(<<<EOT
+Converts Doctrine 1.X schema into a Doctrine 2.X schema.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        // Process source directories
+        $fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
+
+        // Process destination directory
+        $destPath = realpath($input->getArgument('dest-path'));
+
+        $toType = $input->getArgument('to-type');
+        $extend = $input->getOption('extend');
+        $numSpaces = $input->getOption('num-spaces');
+
+        $this->convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output);
+    }
+
+    /**
+     * @param \Doctrine\ORM\EntityManager $em
+     * @param array $fromPaths
+     * @param string $destPath
+     * @param string $toType
+     * @param int $numSpaces
+     * @param string|null $extend
+     * @param Console\Output\OutputInterface $output
+     */
+    public function convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output)
+    {
+        foreach ($fromPaths as &$dirName) {
+            $dirName = realpath($dirName);
+
+            if ( ! file_exists($dirName)) {
+                throw new \InvalidArgumentException(
+                    sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not exist.", $dirName)
+                );
+            } else if ( ! is_readable($dirName)) {
+                throw new \InvalidArgumentException(
+                    sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not have read permissions.", $dirName)
+                );
+            }
+        }
+
+        if ( ! file_exists($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not exist.", $destPath)
+            );
+        } else if ( ! is_writable($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
+            );
+        }
+
+        $cme = $this->getMetadataExporter();
+        $exporter = $cme->getExporter($toType, $destPath);
+
+        if (strtolower($toType) === 'annotation') {
+            $entityGenerator = $this->getEntityGenerator();
+            $exporter->setEntityGenerator($entityGenerator);
+
+            $entityGenerator->setNumSpaces($numSpaces);
+
+            if ($extend !== null) {
+                $entityGenerator->setClassToExtend($extend);
+            }
+        }
+
+        $converter = new ConvertDoctrine1Schema($fromPaths);
+        $metadata = $converter->getMetadata();
+
+        if ($metadata) {
+            $output->write(PHP_EOL);
+
+            foreach ($metadata as $class) {
+                $output->write(sprintf('Processing entity "<info>%s</info>"', $class->name) . PHP_EOL);
+            }
+
+            $exporter->setMetadata($metadata);
+            $exporter->export();
+
+            $output->write(PHP_EOL . sprintf(
+                'Converting Doctrine 1.X schema to "<info>%s</info>" mapping type in "<info>%s</info>"', $toType, $destPath
+            ));
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php	(revision 345)
@@ -0,0 +1,186 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\ORM\Tools\Console\MetadataFilter,
+    Doctrine\ORM\Tools\Export\ClassMetadataExporter,
+    Doctrine\ORM\Tools\EntityGenerator,
+    Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
+
+/**
+ * Command to convert your mapping information between the various formats.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConvertMappingCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:convert-mapping')
+        ->setDescription('Convert mapping information between supported formats.')
+        ->setDefinition(array(
+            new InputOption(
+                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'A string pattern used to match entities that should be processed.'
+            ),
+            new InputArgument(
+                'to-type', InputArgument::REQUIRED, 'The mapping type to be converted.'
+            ),
+            new InputArgument(
+                'dest-path', InputArgument::REQUIRED,
+                'The path to generate your entities classes.'
+            ),
+            new InputOption(
+                'force', null, InputOption::VALUE_NONE,
+                'Force to overwrite existing mapping files.'
+            ),
+            new InputOption(
+                'from-database', null, null, 'Whether or not to convert mapping information from existing database.'
+            ),
+            new InputOption(
+                'extend', null, InputOption::VALUE_OPTIONAL,
+                'Defines a base class to be extended by generated entity classes.'
+            ),
+            new InputOption(
+                'num-spaces', null, InputOption::VALUE_OPTIONAL,
+                'Defines the number of indentation spaces', 4
+            ),
+            new InputOption(
+                'namespace', null, InputOption::VALUE_OPTIONAL,
+                'Defines a namespace for the generated entity classes, if converted from database.'
+            ),
+        ))
+        ->setHelp(<<<EOT
+Convert mapping information between supported formats.
+
+This is an execute <info>one-time</info> command. It should not be necessary for
+you to call this method multiple times, escpecially when using the <comment>--from-database</comment>
+flag.
+
+Converting an existing databsae schema into mapping files only solves about 70-80%
+of the necessary mapping information. Additionally the detection from an existing
+database cannot detect inverse associations, inheritance types,
+entities with foreign keys as primary keys and many of the
+semantical operations on associations such as cascade.
+
+<comment>Hint:</comment> There is no need to convert YAML or XML mapping files to annotations
+every time you make changes. All mapping drivers are first class citizens
+in Doctrine 2 and can be used as runtime mapping for the ORM.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        if ($input->getOption('from-database') === true) {
+            $databaseDriver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
+                $em->getConnection()->getSchemaManager()
+            );
+
+            $em->getConfiguration()->setMetadataDriverImpl(
+                $databaseDriver
+            );
+
+            if (($namespace = $input->getOption('namespace')) !== null) {
+                $databaseDriver->setNamespace($namespace);
+            }
+        }
+
+        $cmf = new DisconnectedClassMetadataFactory();
+        $cmf->setEntityManager($em);
+        $metadata = $cmf->getAllMetadata();
+        $metadata = MetadataFilter::filter($metadata, $input->getOption('filter'));
+
+        // Process destination directory
+        if ( ! is_dir($destPath = $input->getArgument('dest-path'))) {
+            mkdir($destPath, 0777, true);
+        }
+        $destPath = realpath($destPath);
+
+        if ( ! file_exists($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Mapping destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
+            );
+        } else if ( ! is_writable($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
+            );
+        }
+
+        $toType = strtolower($input->getArgument('to-type'));
+
+        $exporter = $this->getExporter($toType, $destPath);
+        $exporter->setOverwriteExistingFiles( ($input->getOption('force') !== false) );
+
+        if ($toType == 'annotation') {
+            $entityGenerator = new EntityGenerator();
+            $exporter->setEntityGenerator($entityGenerator);
+
+            $entityGenerator->setNumSpaces($input->getOption('num-spaces'));
+
+            if (($extend = $input->getOption('extend')) !== null) {
+                $entityGenerator->setClassToExtend($extend);
+            }
+        }
+
+        if (count($metadata)) {
+            foreach ($metadata as $class) {
+                $output->write(sprintf('Processing entity "<info>%s</info>"', $class->name) . PHP_EOL);
+            }
+
+            $exporter->setMetadata($metadata);
+            $exporter->export();
+
+            $output->write(PHP_EOL . sprintf(
+                'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"' . PHP_EOL, $toType, $destPath
+            ));
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+    }
+
+    protected function getExporter($toType, $destPath)
+    {
+        $cme = new ClassMetadataExporter();
+
+        return $cme->getExporter($toType, $destPath);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php	(revision 345)
@@ -0,0 +1,85 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console;
+
+/**
+ * Command to ensure that Doctrine is properly configured for a production environment.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EnsureProductionSettingsCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:ensure-production-settings')
+        ->setDescription('Verify that Doctrine is properly configured for a production environment.')
+        ->setDefinition(array(
+            new InputOption(
+                'complete', null, InputOption::VALUE_NONE,
+                'Flag to also inspect database connection existance.'
+            )
+        ))
+        ->setHelp(<<<EOT
+Verify that Doctrine is properly configured for a production environment.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        $error = false;
+        try {
+            $em->getConfiguration()->ensureProductionSettings();
+
+            if ($input->getOption('complete') !== null) {
+                $em->getConnection()->connect();
+            }
+        } catch (\Exception $e) {
+            $error = true;
+            $output->writeln('<error>' . $e->getMessage() . '</error>');
+        }
+
+        if ($error === false) {
+            $output->write('<info>Environment is correctly configured for production.</info>' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php	(revision 345)
@@ -0,0 +1,163 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\ORM\Tools\Console\MetadataFilter,
+    Doctrine\ORM\Tools\EntityGenerator,
+    Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
+
+/**
+ * Command to generate entity classes and method stubs from your mapping information.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GenerateEntitiesCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:generate-entities')
+        ->setDescription('Generate entity classes and method stubs from your mapping information.')
+        ->setDefinition(array(
+            new InputOption(
+                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'A string pattern used to match entities that should be processed.'
+            ),
+            new InputArgument(
+                'dest-path', InputArgument::REQUIRED, 'The path to generate your entity classes.'
+            ),
+            new InputOption(
+                'generate-annotations', null, InputOption::VALUE_OPTIONAL,
+                'Flag to define if generator should generate annotation metadata on entities.', false
+            ),
+            new InputOption(
+                'generate-methods', null, InputOption::VALUE_OPTIONAL,
+                'Flag to define if generator should generate stub methods on entities.', true
+            ),
+            new InputOption(
+                'regenerate-entities', null, InputOption::VALUE_OPTIONAL,
+                'Flag to define if generator should regenerate entity if it exists.', false
+            ),
+            new InputOption(
+                'update-entities', null, InputOption::VALUE_OPTIONAL,
+                'Flag to define if generator should only update entity if it exists.', true
+            ),
+            new InputOption(
+                'extend', null, InputOption::VALUE_OPTIONAL,
+                'Defines a base class to be extended by generated entity classes.'
+            ),
+            new InputOption(
+                'num-spaces', null, InputOption::VALUE_OPTIONAL,
+                'Defines the number of indentation spaces', 4
+            )
+        ))
+        ->setHelp(<<<EOT
+Generate entity classes and method stubs from your mapping information.
+
+If you use the <comment>--update-entities</comment> or <comment>--regenerate-entities</comment> flags your exisiting
+code gets overwritten. The EntityGenerator will only append new code to your
+file and will not delete the old code. However this approach may still be prone
+to error and we suggest you use code repositories such as GIT or SVN to make
+backups of your code.
+
+It makes sense to generate the entity code if you are using entities as Data
+Access Objects only and dont put much additional logic on them. If you are
+however putting much more logic on the entities you should refrain from using
+the entity-generator and code your entities manually.
+
+<error>Important:</error> Even if you specified Inheritance options in your
+XML or YAML Mapping files the generator cannot generate the base and
+child classes for you correctly, because it doesn't know which
+class is supposed to extend which. You have to adjust the entity
+code manually for inheritance to work!
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        $cmf = new DisconnectedClassMetadataFactory();
+        $cmf->setEntityManager($em);
+        $metadatas = $cmf->getAllMetadata();
+        $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
+
+        // Process destination directory
+        $destPath = realpath($input->getArgument('dest-path'));
+
+        if ( ! file_exists($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
+            );
+        } else if ( ! is_writable($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
+            );
+        }
+
+        if (count($metadatas)) {
+            // Create EntityGenerator
+            $entityGenerator = new EntityGenerator();
+
+            $entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
+            $entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
+            $entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
+            $entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
+            $entityGenerator->setNumSpaces($input->getOption('num-spaces'));
+
+            if (($extend = $input->getOption('extend')) !== null) {
+                $entityGenerator->setClassToExtend($extend);
+            }
+
+            foreach ($metadatas as $metadata) {
+                $output->write(
+                    sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL
+                );
+            }
+
+            // Generating Entities
+            $entityGenerator->generate($metadatas, $destPath);
+
+            // Outputting information message
+            $output->write(PHP_EOL . sprintf('Entity classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php	(revision 345)
@@ -0,0 +1,115 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\ORM\Tools\Console\MetadataFilter;
+
+/**
+ * Command to (re)generate the proxy classes used by doctrine.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GenerateProxiesCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:generate-proxies')
+        ->setDescription('Generates proxy classes for entity classes.')
+        ->setDefinition(array(
+            new InputOption(
+                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'A string pattern used to match entities that should be processed.'
+            ),
+            new InputArgument(
+                'dest-path', InputArgument::OPTIONAL,
+                'The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.'
+            ),
+        ))
+        ->setHelp(<<<EOT
+Generates proxy classes for entity classes.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        $metadatas = $em->getMetadataFactory()->getAllMetadata();
+        $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
+
+        // Process destination directory
+        if (($destPath = $input->getArgument('dest-path')) === null) {
+            $destPath = $em->getConfiguration()->getProxyDir();
+        }
+
+        if ( ! is_dir($destPath)) {
+            mkdir($destPath, 0777, true);
+        }
+
+        $destPath = realpath($destPath);
+
+        if ( ! file_exists($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Proxies destination directory '<info>%s</info>' does not exist.", $em->getConfiguration()->getProxyDir())
+            );
+        } else if ( ! is_writable($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Proxies destination directory '<info>%s</info>' does not have write permissions.", $destPath)
+            );
+        }
+
+        if ( count($metadatas)) {
+            foreach ($metadatas as $metadata) {
+                $output->write(
+                    sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL
+                );
+            }
+
+            // Generating Proxies
+            $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath);
+
+            // Outputting information message
+            $output->write(PHP_EOL . sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php	(revision 345)
@@ -0,0 +1,116 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console,
+    Doctrine\ORM\Tools\Console\MetadataFilter,
+    Doctrine\ORM\Tools\EntityRepositoryGenerator;
+
+/**
+ * Command to generate repository classes for mapping information.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class GenerateRepositoriesCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:generate-repositories')
+        ->setDescription('Generate repository classes from your mapping information.')
+        ->setDefinition(array(
+            new InputOption(
+                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'A string pattern used to match entities that should be processed.'
+            ),
+            new InputArgument(
+                'dest-path', InputArgument::REQUIRED, 'The path to generate your repository classes.'
+            )
+        ))
+        ->setHelp(<<<EOT
+Generate repository classes from your mapping information.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        $metadatas = $em->getMetadataFactory()->getAllMetadata();
+        $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
+
+        // Process destination directory
+        $destPath = realpath($input->getArgument('dest-path'));
+
+        if ( ! file_exists($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
+            );
+        } else if ( ! is_writable($destPath)) {
+            throw new \InvalidArgumentException(
+                sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
+            );
+        }
+
+        if (count($metadatas)) {
+            $numRepositories = 0;
+            $generator = new EntityRepositoryGenerator();
+
+            foreach ($metadatas as $metadata) {
+                if ($metadata->customRepositoryClassName) {
+                    $output->write(
+                        sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName) . PHP_EOL
+                    );
+
+                    $generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath);
+
+                    $numRepositories++;
+                }
+            }
+
+            if ($numRepositories) {
+                // Outputting information message
+                $output->write(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
+            } else {
+                $output->write('No Repository classes were found to be processed.' . PHP_EOL);
+            }
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/InfoCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/InfoCommand.php	(revision 345)
@@ -0,0 +1,80 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Doctrine\ORM\Mapping\MappingException;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * Show information about mapped entities
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class InfoCommand extends Command
+{
+    protected function configure()
+    {
+        $this
+            ->setName('orm:info')
+            ->setDescription('Show basic information about all mapped entities')
+            ->setHelp(<<<EOT
+The <info>doctrine:mapping:info</info> shows basic information about which
+entities exist and possibly if their mapping information contains errors or
+not.
+EOT
+        );
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        /* @var $entityManager \Doctrine\ORM\EntityManager */
+        $entityManager = $this->getHelper('em')->getEntityManager();
+
+        $entityClassNames = $entityManager->getConfiguration()
+                                          ->getMetadataDriverImpl()
+                                          ->getAllClassNames();
+
+        if (!$entityClassNames) {
+            throw new \Exception(
+                'You do not have any mapped Doctrine ORM entities according to the current configuration. '.
+                'If you have entities or mapping files you should check your mapping configuration for errors.'
+            );
+        }
+
+        $output->writeln(sprintf("Found <info>%d</info> mapped entities:", count($entityClassNames)));
+
+        foreach ($entityClassNames as $entityClassName) {
+            try {
+                $cm = $entityManager->getClassMetadata($entityClassName);
+                $output->writeln(sprintf("<info>[OK]</info>   %s", $entityClassName));
+            } catch (MappingException $e) {
+                $output->writeln("<error>[FAIL]</error> ".$entityClassName);
+                $output->writeln(sprintf("<comment>%s</comment>", $e->getMessage()));
+                $output->writeln('');
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php	(revision 345)
@@ -0,0 +1,124 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console;
+
+/**
+ * Command to execute DQL queries in a given EntityManager.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class RunDqlCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:run-dql')
+        ->setDescription('Executes arbitrary DQL directly from the command line.')
+        ->setDefinition(array(
+            new InputArgument('dql', InputArgument::REQUIRED, 'The DQL to execute.'),
+            new InputOption(
+                'hydrate', null, InputOption::VALUE_REQUIRED,
+                'Hydration mode of result set. Should be either: object, array, scalar or single-scalar.',
+                'object'
+            ),
+            new InputOption(
+                'first-result', null, InputOption::VALUE_REQUIRED,
+                'The first result in the result set.'
+            ),
+            new InputOption(
+                'max-result', null, InputOption::VALUE_REQUIRED,
+                'The maximum number of results in the result set.'
+            ),
+            new InputOption(
+                'depth', null, InputOption::VALUE_REQUIRED,
+                'Dumping depth of Entity graph.', 7
+            )
+        ))
+        ->setHelp(<<<EOT
+Executes arbitrary DQL directly from the command line.
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        if (($dql = $input->getArgument('dql')) === null) {
+            throw new \RuntimeException("Argument 'DQL' is required in order to execute this command correctly.");
+        }
+
+        $depth = $input->getOption('depth');
+
+        if ( ! is_numeric($depth)) {
+            throw new \LogicException("Option 'depth' must contains an integer value");
+        }
+
+        $hydrationModeName = $input->getOption('hydrate');
+        $hydrationMode = 'Doctrine\ORM\Query::HYDRATE_' . strtoupper(str_replace('-', '_', $hydrationModeName));
+
+        if ( ! defined($hydrationMode)) {
+            throw new \RuntimeException(
+                "Hydration mode '$hydrationModeName' does not exist. It should be either: object. array, scalar or single-scalar."
+            );
+        }
+
+        $query = $em->createQuery($dql);
+
+        if (($firstResult = $input->getOption('first-result')) !== null) {
+            if ( ! is_numeric($firstResult)) {
+                throw new \LogicException("Option 'first-result' must contains an integer value");
+            }
+
+            $query->setFirstResult((int) $firstResult);
+        }
+
+        if (($maxResult = $input->getOption('max-result')) !== null) {
+            if ( ! is_numeric($maxResult)) {
+                throw new \LogicException("Option 'max-result' must contains an integer value");
+            }
+
+            $query->setMaxResults((int) $maxResult);
+        }
+
+        $resultSet = $query->execute(array(), constant($hydrationMode));
+
+        \Doctrine\Common\Util\Debug::dump($resultSet, $input->getOption('depth'));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php	(revision 345)
@@ -0,0 +1,64 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console\Input\InputInterface,
+    Symfony\Component\Console\Output\OutputInterface,
+    Symfony\Component\Console\Command\Command,
+    Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper,
+    Doctrine\ORM\Tools\SchemaTool,
+    Doctrine\ORM\Mapping\Driver\AbstractFileDriver;
+
+abstract class AbstractCommand extends Command
+{
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @param SchemaTool $schemaTool
+     * @param array $metadatas
+     */
+    abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $emHelper = $this->getHelper('em');
+
+        /* @var $em \Doctrine\ORM\EntityManager */
+        $em = $emHelper->getEntityManager();
+
+        $metadatas = $em->getMetadataFactory()->getAllMetadata();
+
+        if ( ! empty($metadatas)) {
+            // Create SchemaTool
+            $tool = new \Doctrine\ORM\Tools\SchemaTool($em);
+
+            $this->executeSchemaCommand($input, $output, $tool, $metadatas);
+        } else {
+            $output->write('No Metadata Classes to process.' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console\Input\InputInterface,
+    Symfony\Component\Console\Output\OutputInterface,
+    Doctrine\ORM\Tools\SchemaTool;
+
+/**
+ * Command to create the database schema for a set of classes based on their mappings.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class CreateCommand extends AbstractCommand
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:schema-tool:create')
+        ->setDescription(
+            'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.'
+        )
+        ->setDefinition(array(
+            new InputOption(
+                'dump-sql', null, InputOption::VALUE_NONE,
+                'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
+            )
+        ))
+        ->setHelp(<<<EOT
+Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
+EOT
+        );
+    }
+
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    {
+        $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);
+
+        if ($input->getOption('dump-sql') === true) {
+            $sqls = $schemaTool->getCreateSchemaSql($metadatas);
+            $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
+        } else {
+            $output->write('Creating database schema...' . PHP_EOL);
+            $schemaTool->createSchema($metadatas);
+            $output->write('Database schema created successfully!' . PHP_EOL);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php	(revision 345)
@@ -0,0 +1,111 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console\Input\InputInterface,
+    Symfony\Component\Console\Output\OutputInterface,
+    Doctrine\ORM\Tools\SchemaTool;
+
+/**
+ * Command to drop the database schema for a set of classes based on their mappings.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class DropCommand extends AbstractCommand
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:schema-tool:drop')
+        ->setDescription(
+            'Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.'
+        )
+        ->setDefinition(array(
+            new InputOption(
+                'dump-sql', null, InputOption::VALUE_NONE,
+                'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
+            ),
+            new InputOption(
+                'force', null, InputOption::VALUE_NONE,
+                "Don't ask for the deletion of the database, but force the operation to run."
+            ),
+            new InputOption(
+                'full-database', null, InputOption::VALUE_NONE,
+                'Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains.'
+            ),
+        ))
+        ->setHelp(<<<EOT
+Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output.
+Beware that the complete database is dropped by this command, even tables that are not relevant to your metadata model.
+EOT
+        );
+    }
+
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    {
+        $isFullDatabaseDrop = ($input->getOption('full-database'));
+
+        if ($input->getOption('dump-sql') === true) {
+            if ($isFullDatabaseDrop) {
+                $sqls = $schemaTool->getDropDatabaseSQL();
+            } else {
+                $sqls = $schemaTool->getDropSchemaSQL($metadatas);
+            }
+            $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
+        } else if ($input->getOption('force') === true) {
+            $output->write('Dropping database schema...' . PHP_EOL);
+            if ($isFullDatabaseDrop) {
+                $schemaTool->dropDatabase();
+            } else {
+                $schemaTool->dropSchema($metadatas);
+            }
+            $output->write('Database schema dropped successfully!' . PHP_EOL);
+        } else {
+            $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);
+
+            if ($isFullDatabaseDrop) {
+                $sqls = $schemaTool->getDropDatabaseSQL();
+            } else {
+                $sqls = $schemaTool->getDropSchemaSQL($metadatas);
+            }
+
+            if (count($sqls)) {
+                $output->write('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.' . PHP_EOL);
+                $output->write('Please run the operation with --force to execute these queries or use --dump-sql to see them.' . PHP_EOL);
+            } else {
+                $output->write('Nothing to drop. The database is empty!' . PHP_EOL);
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php	(revision 345)
@@ -0,0 +1,135 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console\Input\InputInterface,
+    Symfony\Component\Console\Output\OutputInterface,
+    Doctrine\ORM\Tools\SchemaTool;
+
+/**
+ * Command to generate the SQL needed to update the database schema to match
+ * the current mapping information.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Ryan Weaver <ryan@thatsquality.com>
+ */
+class UpdateCommand extends AbstractCommand
+{
+    protected $name = 'orm:schema-tool:update';
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName($this->name)
+        ->setDescription(
+            'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.'
+        )
+        ->setDefinition(array(
+            new InputOption(
+                'complete', null, InputOption::VALUE_NONE,
+                'If defined, all assets of the database which are not relevant to the current metadata will be dropped.'
+            ),
+
+            new InputOption(
+                'dump-sql', null, InputOption::VALUE_NONE,
+                'Dumps the generated SQL statements to the screen (does not execute them).'
+            ),
+            new InputOption(
+                'force', null, InputOption::VALUE_NONE,
+                'Causes the generated SQL statements to be physically executed against your database.'
+            ),
+        ));
+
+        $fullName = $this->getName();
+        $this->setHelp(<<<EOT
+The <info>$fullName</info> command generates the SQL needed to
+synchronize the database schema with the current mapping metadata of the
+default entity manager.
+
+For example, if you add metadata for a new column to an entity, this command
+would generate and output the SQL needed to add the new column to the database:
+
+<info>$fullName --dump-sql</info>
+
+Alternatively, you can execute the generated queries:
+
+<info>$fullName --force</info>
+
+Finally, be aware that if the <info>--complete</info> option is passed, this
+task will drop all database assets (e.g. tables, etc) that are *not* described
+by the current metadata. In other words, without this option, this task leaves
+untouched any "extra" tables that exist in the database, but which aren't
+described by any metadata.
+EOT
+        );
+    }
+
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    {
+        // Defining if update is complete or not (--complete not defined means $saveMode = true)
+        $saveMode = ($input->getOption('complete') !== true);
+
+        $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
+        if (0 == count($sqls)) {
+            $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');
+
+            return;
+        }
+
+        $dumpSql = (true === $input->getOption('dump-sql'));
+        $force = (true === $input->getOption('force'));
+        if ($dumpSql && $force) {
+            throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).');
+        }
+
+        if ($dumpSql) {
+            $output->writeln(implode(';' . PHP_EOL, $sqls));
+        } else if ($force) {
+            $output->writeln('Updating database schema...');
+            $schemaTool->updateSchema($metadatas, $saveMode);
+            $output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" queries were executed', count($sqls)));
+        } else {
+            $output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
+            $output->writeln('           Use the incremental update to detect changes during development and use');
+            $output->writeln('           the SQL DDL provided to manually update your database in production.');
+            $output->writeln('');
+
+            $output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
+            $output->writeln('Please run the operation by passing one of the following options:');
+
+            $output->writeln(sprintf('    <info>%s --force</info> to execute the command', $this->getName()));
+            $output->writeln(sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php	(revision 345)
@@ -0,0 +1,89 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument,
+    Symfony\Component\Console\Input\InputOption,
+    Symfony\Component\Console;
+
+/**
+ * Validate that the current mapping is valid
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class ValidateSchemaCommand extends Console\Command\Command
+{
+    /**
+     * @see Console\Command\Command
+     */
+    protected function configure()
+    {
+        $this
+        ->setName('orm:validate-schema')
+        ->setDescription('Validate the mapping files.')
+        ->setHelp(<<<EOT
+'Validate that the mapping files are correct and in sync with the database.'
+EOT
+        );
+    }
+
+    /**
+     * @see Console\Command\Command
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $em = $this->getHelper('em')->getEntityManager();
+
+        $validator = new \Doctrine\ORM\Tools\SchemaValidator($em);
+        $errors = $validator->validateMapping();
+
+        $exit = 0;
+        if ($errors) {
+            foreach ($errors AS $className => $errorMessages) {
+                $output->write("<error>[Mapping]  FAIL - The entity-class '" . $className . "' mapping is invalid:</error>\n");
+                foreach ($errorMessages AS $errorMessage) {
+                    $output->write('* ' . $errorMessage . "\n");
+                }
+                $output->write("\n");
+            }
+            $exit += 1;
+        } else {
+            $output->write('<info>[Mapping]  OK - The mapping files are correct.</info>' . "\n");
+        }
+
+        if (!$validator->schemaInSyncWithMetadata()) {
+            $output->write('<error>[Database] FAIL - The database schema is not in sync with the current mapping file.</error>' . "\n");
+            $exit += 2;
+        } else {
+            $output->write('<info>[Database] OK - The database schema is in sync with the mapping files.</info>' . "\n");
+        }
+
+        return $exit;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/ConsoleRunner.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/ConsoleRunner.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/ConsoleRunner.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+
+class ConsoleRunner
+{
+    /**
+     * Run console with the given helperset.
+     *
+     * @param \Symfony\Component\Console\Helper\HelperSet $helperSet
+     * @return void
+     */
+    static public function run(HelperSet $helperSet)
+    {
+        $cli = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION);
+        $cli->setCatchExceptions(true);
+        $cli->setHelperSet($helperSet);
+        self::addCommands($cli);
+        $cli->run();
+    }
+
+    /**
+     * @param Application $cli
+     */
+    static public function addCommands(Application $cli)
+    {
+        $cli->addCommands(array(
+            // DBAL Commands
+            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
+            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
+
+            // ORM Commands
+            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
+            new \Doctrine\ORM\Tools\Console\Command\InfoCommand()
+        ));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php	(revision 345)
@@ -0,0 +1,74 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Console\Helper;
+
+use Symfony\Component\Console\Helper\Helper,
+    Doctrine\ORM\EntityManager;
+
+/**
+ * Doctrine CLI Connection Helper.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EntityManagerHelper extends Helper
+{
+    /**
+     * Doctrine ORM EntityManager
+     * @var EntityManager
+     */
+    protected $_em;
+
+    /**
+     * Constructor
+     *
+     * @param Connection $connection Doctrine Database Connection
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em = $em;
+    }
+
+    /**
+     * Retrieves Doctrine ORM EntityManager
+     *
+     * @return EntityManager
+     */
+    public function getEntityManager()
+    {
+        return $this->_em;
+    }
+
+    /**
+     * @see Helper
+     */
+    public function getName()
+    {
+        return 'entityManager';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/MetadataFilter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/MetadataFilter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Console/MetadataFilter.php	(revision 345)
@@ -0,0 +1,80 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools\Console;
+
+/**
+ * Used by CLI Tools to restrict entity-based commands to given patterns.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class MetadataFilter extends \FilterIterator implements \Countable
+{
+    /**
+     * Filter Metadatas by one or more filter options.
+     *
+     * @param array $metadatas
+     * @param array|string $filter
+     * @return array
+     */
+    static public function filter(array $metadatas, $filter)
+    {
+        $metadatas = new MetadataFilter(new \ArrayIterator($metadatas), $filter);
+        return iterator_to_array($metadatas);
+    }
+
+    private $_filter = array();
+
+    public function __construct(\ArrayIterator $metadata, $filter)
+    {
+        $this->_filter = (array)$filter;
+        parent::__construct($metadata);
+    }
+
+    public function accept()
+    {
+        if (count($this->_filter) == 0) {
+            return true;
+        }
+
+        $it = $this->getInnerIterator();
+        $metadata = $it->current();
+
+        foreach ($this->_filter AS $filter) {
+            if (strpos($metadata->name, $filter) !== false) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public function count()
+    {
+        return count($this->getInnerIterator());
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php	(revision 345)
@@ -0,0 +1,274 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Tools\Export\Driver\AbstractExporter,
+    Doctrine\Common\Util\Inflector;
+
+/**
+ * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ConvertDoctrine1Schema
+{
+    private $_legacyTypeMap = array(
+        // TODO: This list may need to be updated
+        'clob' => 'text',
+        'timestamp' => 'datetime',
+        'enum' => 'string'
+    );
+
+    /**
+     * Constructor passes the directory or array of directories
+     * to convert the Doctrine 1 schema files from
+     *
+     * @param array $from
+     * @author Jonathan Wage
+     */
+    public function __construct($from)
+    {
+        $this->_from = (array) $from;
+    }
+
+    /**
+     * Get an array of ClassMetadataInfo instances from the passed
+     * Doctrine 1 schema
+     *
+     * @return array $metadatas  An array of ClassMetadataInfo instances
+     */
+    public function getMetadata()
+    {
+        $schema = array();
+        foreach ($this->_from as $path) {
+            if (is_dir($path)) {
+                $files = glob($path . '/*.yml');
+                foreach ($files as $file) {
+                    $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file));
+                }
+            } else {
+                $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path));
+            }
+        }
+
+        $metadatas = array();
+        foreach ($schema as $className => $mappingInformation) {
+            $metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation);
+        }
+
+        return $metadatas;
+    }
+
+    private function _convertToClassMetadataInfo($className, $mappingInformation)
+    {
+        $metadata = new ClassMetadataInfo($className);
+
+        $this->_convertTableName($className, $mappingInformation, $metadata);
+        $this->_convertColumns($className, $mappingInformation, $metadata);
+        $this->_convertIndexes($className, $mappingInformation, $metadata);
+        $this->_convertRelations($className, $mappingInformation, $metadata);
+
+        return $metadata;
+    }
+
+    private function _convertTableName($className, array $model, ClassMetadataInfo $metadata)
+    {
+        if (isset($model['tableName']) && $model['tableName']) {
+            $e = explode('.', $model['tableName']);
+
+            if (count($e) > 1) {
+                $metadata->table['schema'] = $e[0];
+                $metadata->table['name'] = $e[1];
+            } else {
+                $metadata->table['name'] = $e[0];
+            }
+        }
+    }
+
+    private function _convertColumns($className, array $model, ClassMetadataInfo $metadata)
+    {
+        $id = false;
+
+        if (isset($model['columns']) && $model['columns']) {
+            foreach ($model['columns'] as $name => $column) {
+                $fieldMapping = $this->_convertColumn($className, $name, $column, $metadata);
+
+                if (isset($fieldMapping['id']) && $fieldMapping['id']) {
+                    $id = true;
+                }
+            }
+        }
+
+        if ( ! $id) {
+            $fieldMapping = array(
+                'fieldName' => 'id',
+                'columnName' => 'id',
+                'type' => 'integer',
+                'id' => true
+            );
+            $metadata->mapField($fieldMapping);
+            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+        }
+    }
+
+    private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
+    {
+        if (is_string($column)) {
+            $string = $column;
+            $column = array();
+            $column['type'] = $string;
+        }
+        if ( ! isset($column['name'])) {
+            $column['name'] = $name;
+        }
+        // check if a column alias was used (column_name as field_name)
+        if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
+            $name = $matches[1];
+            $column['name'] = $name;
+            $column['alias'] = $matches[2];
+        }
+        if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
+            $column['type'] = $matches[1];
+            $column['length'] = $matches[2];
+        }
+        $column['type'] = strtolower($column['type']);
+        // check if legacy column type (1.x) needs to be mapped to a 2.0 one
+        if (isset($this->_legacyTypeMap[$column['type']])) {
+            $column['type'] = $this->_legacyTypeMap[$column['type']];
+        }
+        if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) {
+            throw ToolsException::couldNotMapDoctrine1Type($column['type']);
+        }
+
+        $fieldMapping = array();
+        if (isset($column['primary'])) {
+            $fieldMapping['id'] = true;
+        }
+        $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
+        $fieldMapping['columnName'] = $column['name'];
+        $fieldMapping['type'] = $column['type'];
+        if (isset($column['length'])) {
+            $fieldMapping['length'] = $column['length'];
+        }
+        $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
+        foreach ($column as $key => $value) {
+            if (in_array($key, $allowed)) {
+                $fieldMapping[$key] = $value;
+            }
+        }
+
+        $metadata->mapField($fieldMapping);
+
+        if (isset($column['autoincrement'])) {
+            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+        } else if (isset($column['sequence'])) {
+            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
+            $definition = array(
+                'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
+            );
+            if (isset($column['sequence']['size'])) {
+                $definition['allocationSize'] = $column['sequence']['size'];
+            }
+            if (isset($column['sequence']['value'])) {
+                $definition['initialValue'] = $column['sequence']['value'];
+            }
+            $metadata->setSequenceGeneratorDefinition($definition);
+        }
+        return $fieldMapping;
+    }
+
+    private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata)
+    {
+        if (isset($model['indexes']) && $model['indexes']) {
+            foreach ($model['indexes'] as $name => $index) {
+                $type = (isset($index['type']) && $index['type'] == 'unique')
+                    ? 'uniqueConstraints' : 'indexes';
+
+                $metadata->table[$type][$name] = array(
+                    'columns' => $index['fields']
+                );
+            }
+        }
+    }
+
+    private function _convertRelations($className, array $model, ClassMetadataInfo $metadata)
+    {
+        if (isset($model['relations']) && $model['relations']) {
+            foreach ($model['relations'] as $name => $relation) {
+                if ( ! isset($relation['alias'])) {
+                    $relation['alias'] = $name;
+                }
+                if ( ! isset($relation['class'])) {
+                    $relation['class'] = $name;
+                }
+                if ( ! isset($relation['local'])) {
+                    $relation['local'] = Inflector::tableize($relation['class']);
+                }
+                if ( ! isset($relation['foreign'])) {
+                    $relation['foreign'] = 'id';
+                }
+                if ( ! isset($relation['foreignAlias'])) {
+                    $relation['foreignAlias'] = $className;
+                }
+
+                if (isset($relation['refClass'])) {
+                    $type = 'many';
+                    $foreignType = 'many';
+                    $joinColumns = array();
+                } else {
+                    $type = isset($relation['type']) ? $relation['type'] : 'one';
+                    $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
+                    $joinColumns = array(
+                        array(
+                            'name' => $relation['local'],
+                            'referencedColumnName' => $relation['foreign'],
+                            'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
+                        )
+                    );
+                }
+
+                if ($type == 'one' && $foreignType == 'one') {
+                    $method = 'mapOneToOne';
+                } else if ($type == 'many' && $foreignType == 'many') {
+                    $method = 'mapManyToMany';
+                } else {
+                    $method = 'mapOneToMany';
+                }
+
+                $associationMapping = array();
+                $associationMapping['fieldName'] = $relation['alias'];
+                $associationMapping['targetEntity'] = $relation['class'];
+                $associationMapping['mappedBy'] = $relation['foreignAlias'];
+                $associationMapping['joinColumns'] = $joinColumns;
+
+                $metadata->$method($associationMapping);
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php	(revision 345)
@@ -0,0 +1,151 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\Event\OnFlushEventArgs;
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\PersistentCollection;
+use Doctrine\ORM\UnitOfWork;
+
+/**
+ * Use this logger to dump the identity map during the onFlush event. This is useful for debugging
+ * weird UnitOfWork behavior with complex operations.
+ */
+class DebugUnitOfWorkListener
+{
+    private $file;
+    private $context;
+
+    /**
+     * Pass a stream and contet information for the debugging session.
+     *
+     * The stream can be php://output to print to the screen.
+     *
+     * @param string $file
+     * @param string $context
+     */
+    public function __construct($file = 'php://output', $context = '')
+    {
+        $this->file = $file;
+        $this->context = $context;
+    }
+
+    public function onFlush(OnFlushEventArgs $args)
+    {
+        $this->dumpIdentityMap($args->getEntityManager());
+    }
+
+    /**
+     * Dump the contents of the identity map into a stream.
+     *
+     * @param EntityManager $em
+     * @return void
+     */
+    public function dumpIdentityMap(EntityManager $em)
+    {
+        $uow = $em->getUnitOfWork();
+        $identityMap = $uow->getIdentityMap();
+
+        $fh = fopen($this->file, "x+");
+        if (count($identityMap) == 0) {
+            fwrite($fh, "Flush Operation [".$this->context."] - Empty identity map.\n");
+            return;
+        }
+
+        fwrite($fh, "Flush Operation [".$this->context."] - Dumping identity map:\n");
+        foreach ($identityMap AS $className => $map) {
+            fwrite($fh, "Class: ". $className . "\n");
+            foreach ($map AS $idHash => $entity) {
+                fwrite($fh, " Entity: " . $this->getIdString($entity, $uow) . " " . spl_object_hash($entity)."\n");
+                fwrite($fh, "  Associations:\n");
+
+                $cm = $em->getClassMetadata($className);
+                foreach ($cm->associationMappings AS $field => $assoc) {
+                    fwrite($fh, "   " . $field . " ");
+                    $value = $cm->reflFields[$field]->getValue($entity);
+
+                    if ($assoc['type'] & ClassMetadata::TO_ONE) {
+                        if ($value === null) {
+                            fwrite($fh, " NULL\n");
+                        } else {
+                            if ($value instanceof Proxy && !$value->__isInitialized__) {
+                                fwrite($fh, "[PROXY] ");
+                            }
+
+                            fwrite($fh, $this->getIdString($value, $uow) . " " . spl_object_hash($value) . "\n");
+                        }
+                    } else {
+                        $initialized = !($value instanceof PersistentCollection) || $value->isInitialized();
+                        if ($value === null) {
+                            fwrite($fh, " NULL\n");
+                        } else if ($initialized) {
+                            fwrite($fh, "[INITIALIZED] " . $this->getType($value). " " . count($value) . " elements\n");
+                            foreach ($value AS $obj) {
+                                fwrite($fh, "    " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n");
+                            }
+                        } else {
+                            fwrite($fh, "[PROXY] " . $this->getType($value) . " unknown element size\n");
+                            foreach ($value->unwrap() AS $obj) {
+                                fwrite($fh, "    " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        fclose($fh);
+    }
+
+    private function getType($var)
+    {
+        if (is_object($var)) {
+            $refl = new \ReflectionObject($var);
+            return $refl->getShortname();
+        } else {
+            return gettype($var);
+        }
+    }
+
+    private function getIdString($entity, $uow)
+    {
+        if ($uow->isInIdentityMap($entity)) {
+            $ids = $uow->getEntityIdentifier($entity);
+            $idstring = "";
+            foreach ($ids AS $k => $v) {
+                $idstring .= $k."=".$v;
+            }
+        } else {
+            $idstring = "NEWOBJECT ";
+        }
+
+        $state = $uow->getEntityState($entity);
+        if ($state == UnitOfWork::STATE_NEW) {
+            $idstring .= " [NEW]";
+        } else if ($state == UnitOfWork::STATE_REMOVED) {
+            $idstring .= " [REMOVED]";
+        } else if ($state == UnitOfWork::STATE_MANAGED) {
+            $idstring .= " [MANAGED]";
+        } else if ($state == UnitOfwork::STATE_DETACHED) {
+            $idstring .= " [DETACHED]";
+        }
+
+        return $idstring;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\Mapping\ClassMetadataFactory;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * The DisconnectedClassMetadataFactory is used to create ClassMetadataInfo objects
+ * that do not require the entity class actually exist. This allows us to
+ * load some mapping information and use it to do things like generate code
+ * from the mapping information.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class DisconnectedClassMetadataFactory extends ClassMetadataFactory
+{
+    public function getReflectionService()
+    {
+        return new \Doctrine\Common\Persistence\Mapping\StaticReflectionService;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityGenerator.php	(revision 345)
@@ -0,0 +1,1146 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\Common\Util\Inflector,
+    Doctrine\DBAL\Types\Type;
+
+/**
+ * Generic class used to generate PHP5 entity classes from ClassMetadataInfo instances
+ *
+ *     [php]
+ *     $classes = $em->getClassMetadataFactory()->getAllMetadata();
+ *
+ *     $generator = new \Doctrine\ORM\Tools\EntityGenerator();
+ *     $generator->setGenerateAnnotations(true);
+ *     $generator->setGenerateStubMethods(true);
+ *     $generator->setRegenerateEntityIfExists(false);
+ *     $generator->setUpdateEntityIfExists(true);
+ *     $generator->generate($classes, '/path/to/generate/entities');
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EntityGenerator
+{
+    /**
+     * @var bool
+     */
+    private $_backupExisting = true;
+
+    /** The extension to use for written php files */
+    private $_extension = '.php';
+
+    /** Whether or not the current ClassMetadataInfo instance is new or old */
+    private $_isNew = true;
+
+    private $_staticReflection = array();
+
+    /** Number of spaces to use for indention in generated code */
+    private $_numSpaces = 4;
+
+    /** The actual spaces to use for indention */
+    private $_spaces = '    ';
+
+    /** The class all generated entities should extend */
+    private $_classToExtend;
+
+    /** Whether or not to generation annotations */
+    private $_generateAnnotations = false;
+
+    /**
+     * @var string
+     */
+    private $_annotationsPrefix = '';
+
+    /** Whether or not to generated sub methods */
+    private $_generateEntityStubMethods = false;
+
+    /** Whether or not to update the entity class if it exists already */
+    private $_updateEntityIfExists = false;
+
+    /** Whether or not to re-generate entity class if it exists already */
+    private $_regenerateEntityIfExists = false;
+
+    private static $_classTemplate =
+'<?php
+
+<namespace>
+
+use Doctrine\ORM\Mapping as ORM;
+
+<entityAnnotation>
+<entityClassName>
+{
+<entityBody>
+}';
+
+    private static $_getMethodTemplate =
+'/**
+ * <description>
+ *
+ * @return <variableType>
+ */
+public function <methodName>()
+{
+<spaces>return $this-><fieldName>;
+}';
+
+    private static $_setMethodTemplate =
+'/**
+ * <description>
+ *
+ * @param <variableType>$<variableName>
+ * @return <entity>
+ */
+public function <methodName>(<methodTypeHint>$<variableName><variableDefault>)
+{
+<spaces>$this-><fieldName> = $<variableName>;
+<spaces>return $this;
+}';
+
+    private static $_addMethodTemplate =
+'/**
+ * <description>
+ *
+ * @param <variableType>$<variableName>
+ * @return <entity>
+ */
+public function <methodName>(<methodTypeHint>$<variableName>)
+{
+<spaces>$this-><fieldName>[] = $<variableName>;
+<spaces>return $this;
+}';
+
+    /**
+     * @var string
+     */
+    private static $_removeMethodTemplate =
+'/**
+ * <description>
+ *
+ * @param <variableType>$<variableName>
+ */
+public function <methodName>(<methodTypeHint>$<variableName>)
+{
+<spaces>$this-><fieldName>->removeElement($<variableName>);
+}';
+
+    /**
+     * @var string
+     */
+    private static $_lifecycleCallbackMethodTemplate =
+'/**
+ * @<name>
+ */
+public function <methodName>()
+{
+<spaces>// Add your code here
+}';
+
+    private static $_constructorMethodTemplate =
+'public function __construct()
+{
+<spaces><collections>
+}
+';
+
+    public function __construct()
+    {
+        if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) {
+            $this->_annotationsPrefix = 'ORM\\';
+        }
+    }
+
+    /**
+     * Generate and write entity classes for the given array of ClassMetadataInfo instances
+     *
+     * @param array $metadatas
+     * @param string $outputDirectory
+     * @return void
+     */
+    public function generate(array $metadatas, $outputDirectory)
+    {
+        foreach ($metadatas as $metadata) {
+            $this->writeEntityClass($metadata, $outputDirectory);
+        }
+    }
+
+    /**
+     * Generated and write entity class to disk for the given ClassMetadataInfo instance
+     *
+     * @param ClassMetadataInfo $metadata
+     * @param string $outputDirectory
+     * @return void
+     */
+    public function writeEntityClass(ClassMetadataInfo $metadata, $outputDirectory)
+    {
+        $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->_extension;
+        $dir = dirname($path);
+
+        if ( ! is_dir($dir)) {
+            mkdir($dir, 0777, true);
+        }
+
+        $this->_isNew = !file_exists($path) || (file_exists($path) && $this->_regenerateEntityIfExists);
+
+        if ( ! $this->_isNew) {
+            $this->_parseTokensInEntityFile(file_get_contents($path));
+        } else {
+            $this->_staticReflection[$metadata->name] = array('properties' => array(), 'methods' => array());
+        }
+
+        if ($this->_backupExisting && file_exists($path)) {
+            $backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . "~";
+            if (!copy($path, $backupPath)) {
+                throw new \RuntimeException("Attempt to backup overwritten entity file but copy operation failed.");
+            }
+        }
+
+        // If entity doesn't exist or we're re-generating the entities entirely
+        if ($this->_isNew) {
+            file_put_contents($path, $this->generateEntityClass($metadata));
+        // If entity exists and we're allowed to update the entity class
+        } else if ( ! $this->_isNew && $this->_updateEntityIfExists) {
+            file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path));
+        }
+    }
+
+    /**
+     * Generate a PHP5 Doctrine 2 entity class from the given ClassMetadataInfo instance
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return string $code
+     */
+    public function generateEntityClass(ClassMetadataInfo $metadata)
+    {
+        $placeHolders = array(
+            '<namespace>',
+            '<entityAnnotation>',
+            '<entityClassName>',
+            '<entityBody>'
+        );
+
+        $replacements = array(
+            $this->_generateEntityNamespace($metadata),
+            $this->_generateEntityDocBlock($metadata),
+            $this->_generateEntityClassName($metadata),
+            $this->_generateEntityBody($metadata)
+        );
+
+        $code = str_replace($placeHolders, $replacements, self::$_classTemplate);
+        return str_replace('<spaces>', $this->_spaces, $code);
+    }
+
+    /**
+     * Generate the updated code for the given ClassMetadataInfo and entity at path
+     *
+     * @param ClassMetadataInfo $metadata
+     * @param string $path
+     * @return string $code;
+     */
+    public function generateUpdatedEntityClass(ClassMetadataInfo $metadata, $path)
+    {
+        $currentCode = file_get_contents($path);
+
+        $body = $this->_generateEntityBody($metadata);
+        $body = str_replace('<spaces>', $this->_spaces, $body);
+        $last = strrpos($currentCode, '}');
+
+        return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : ''). "}";
+    }
+
+    /**
+     * Set the number of spaces the exported class should have
+     *
+     * @param integer $numSpaces
+     * @return void
+     */
+    public function setNumSpaces($numSpaces)
+    {
+        $this->_spaces = str_repeat(' ', $numSpaces);
+        $this->_numSpaces = $numSpaces;
+    }
+
+    /**
+     * Set the extension to use when writing php files to disk
+     *
+     * @param string $extension
+     * @return void
+     */
+    public function setExtension($extension)
+    {
+        $this->_extension = $extension;
+    }
+
+    /**
+     * Set the name of the class the generated classes should extend from
+     *
+     * @return void
+     */
+    public function setClassToExtend($classToExtend)
+    {
+        $this->_classToExtend = $classToExtend;
+    }
+
+    /**
+     * Set whether or not to generate annotations for the entity
+     *
+     * @param bool $bool
+     * @return void
+     */
+    public function setGenerateAnnotations($bool)
+    {
+        $this->_generateAnnotations = $bool;
+    }
+
+    /**
+     * Set an annotation prefix.
+     *
+     * @param string $prefix
+     */
+    public function setAnnotationPrefix($prefix)
+    {
+        $this->_annotationsPrefix = $prefix;
+    }
+
+    /**
+     * Set whether or not to try and update the entity if it already exists
+     *
+     * @param bool $bool
+     * @return void
+     */
+    public function setUpdateEntityIfExists($bool)
+    {
+        $this->_updateEntityIfExists = $bool;
+    }
+
+    /**
+     * Set whether or not to regenerate the entity if it exists
+     *
+     * @param bool $bool
+     * @return void
+     */
+    public function setRegenerateEntityIfExists($bool)
+    {
+        $this->_regenerateEntityIfExists = $bool;
+    }
+
+    /**
+     * Set whether or not to generate stub methods for the entity
+     *
+     * @param bool $bool
+     * @return void
+     */
+    public function setGenerateStubMethods($bool)
+    {
+        $this->_generateEntityStubMethods = $bool;
+    }
+
+    /**
+     * Should an existing entity be backed up if it already exists?
+     */
+    public function setBackupExisting($bool)
+    {
+        $this->_backupExisting = $bool;
+    }
+
+    private function _generateEntityNamespace(ClassMetadataInfo $metadata)
+    {
+        if ($this->_hasNamespace($metadata)) {
+            return 'namespace ' . $this->_getNamespace($metadata) .';';
+        }
+    }
+
+    private function _generateEntityClassName(ClassMetadataInfo $metadata)
+    {
+        return 'class ' . $this->_getClassName($metadata) .
+            ($this->_extendsClass() ? ' extends ' . $this->_getClassToExtendName() : null);
+    }
+
+    private function _generateEntityBody(ClassMetadataInfo $metadata)
+    {
+        $fieldMappingProperties = $this->_generateEntityFieldMappingProperties($metadata);
+        $associationMappingProperties = $this->_generateEntityAssociationMappingProperties($metadata);
+        $stubMethods = $this->_generateEntityStubMethods ? $this->_generateEntityStubMethods($metadata) : null;
+        $lifecycleCallbackMethods = $this->_generateEntityLifecycleCallbackMethods($metadata);
+
+        $code = array();
+
+        if ($fieldMappingProperties) {
+            $code[] = $fieldMappingProperties;
+        }
+
+        if ($associationMappingProperties) {
+            $code[] = $associationMappingProperties;
+        }
+
+        $code[] = $this->_generateEntityConstructor($metadata);
+
+        if ($stubMethods) {
+            $code[] = $stubMethods;
+        }
+
+        if ($lifecycleCallbackMethods) {
+            $code[] = $lifecycleCallbackMethods;
+        }
+
+        return implode("\n", $code);
+    }
+
+    private function _generateEntityConstructor(ClassMetadataInfo $metadata)
+    {
+        if ($this->_hasMethod('__construct', $metadata)) {
+            return '';
+        }
+
+        $collections = array();
+
+        foreach ($metadata->associationMappings AS $mapping) {
+            if ($mapping['type'] & ClassMetadataInfo::TO_MANY) {
+                $collections[] = '$this->'.$mapping['fieldName'].' = new \Doctrine\Common\Collections\ArrayCollection();';
+            }
+        }
+
+        if ($collections) {
+            return $this->_prefixCodeWithSpaces(str_replace("<collections>", implode("\n".$this->_spaces, $collections), self::$_constructorMethodTemplate));
+        }
+
+        return '';
+    }
+
+    /**
+     * @todo this won't work if there is a namespace in brackets and a class outside of it.
+     * @param string $src
+     */
+    private function _parseTokensInEntityFile($src)
+    {
+        $tokens = token_get_all($src);
+        $lastSeenNamespace = "";
+        $lastSeenClass = false;
+
+        $inNamespace = false;
+        $inClass = false;
+        for ($i = 0; $i < count($tokens); $i++) {
+            $token = $tokens[$i];
+            if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) {
+                continue;
+            }
+
+            if ($inNamespace) {
+                if ($token[0] == T_NS_SEPARATOR || $token[0] == T_STRING) {
+                    $lastSeenNamespace .= $token[1];
+                } else if (is_string($token) && in_array($token, array(';', '{'))) {
+                    $inNamespace = false;
+                }
+            }
+
+            if ($inClass) {
+                $inClass = false;
+                $lastSeenClass = $lastSeenNamespace . ($lastSeenNamespace ? '\\' : '') . $token[1];
+                $this->_staticReflection[$lastSeenClass]['properties'] = array();
+                $this->_staticReflection[$lastSeenClass]['methods'] = array();
+            }
+
+            if ($token[0] == T_NAMESPACE) {
+                $lastSeenNamespace = "";
+                $inNamespace = true;
+            } else if ($token[0] == T_CLASS) {
+                $inClass = true;
+            } else if ($token[0] == T_FUNCTION) {
+                if ($tokens[$i+2][0] == T_STRING) {
+                    $this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1];
+                } else if ($tokens[$i+2] == "&" && $tokens[$i+3][0] == T_STRING) {
+                    $this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+3][1];
+                }
+            } else if (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i+2][0] != T_FUNCTION) {
+                $this->_staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i+2][1], 1);
+            }
+        }
+    }
+
+    private function _hasProperty($property, ClassMetadataInfo $metadata)
+    {
+        if ($this->_extendsClass()) {
+            // don't generate property if its already on the base class.
+            $reflClass = new \ReflectionClass($this->_getClassToExtend());
+            if ($reflClass->hasProperty($property)) {
+                return true;
+            }
+        }
+
+        return (
+            isset($this->_staticReflection[$metadata->name]) &&
+            in_array($property, $this->_staticReflection[$metadata->name]['properties'])
+        );
+    }
+
+    private function _hasMethod($method, ClassMetadataInfo $metadata)
+    {
+        if ($this->_extendsClass()) {
+            // don't generate method if its already on the base class.
+            $reflClass = new \ReflectionClass($this->_getClassToExtend());
+            if ($reflClass->hasMethod($method)) {
+                return true;
+            }
+        }
+
+        return (
+            isset($this->_staticReflection[$metadata->name]) &&
+            in_array($method, $this->_staticReflection[$metadata->name]['methods'])
+        );
+    }
+
+    private function _hasNamespace(ClassMetadataInfo $metadata)
+    {
+        return strpos($metadata->name, '\\') ? true : false;
+    }
+
+    private function _extendsClass()
+    {
+        return $this->_classToExtend ? true : false;
+    }
+
+    private function _getClassToExtend()
+    {
+        return $this->_classToExtend;
+    }
+
+    private function _getClassToExtendName()
+    {
+        $refl = new \ReflectionClass($this->_getClassToExtend());
+
+        return '\\' . $refl->getName();
+    }
+
+    private function _getClassName(ClassMetadataInfo $metadata)
+    {
+        return ($pos = strrpos($metadata->name, '\\'))
+            ? substr($metadata->name, $pos + 1, strlen($metadata->name)) : $metadata->name;
+    }
+
+    private function _getNamespace(ClassMetadataInfo $metadata)
+    {
+        return substr($metadata->name, 0, strrpos($metadata->name, '\\'));
+    }
+
+    private function _generateEntityDocBlock(ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+        $lines[] = '/**';
+        $lines[] = ' * '.$metadata->name;
+
+        if ($this->_generateAnnotations) {
+            $lines[] = ' *';
+
+            $methods = array(
+                '_generateTableAnnotation',
+                '_generateInheritanceAnnotation',
+                '_generateDiscriminatorColumnAnnotation',
+                '_generateDiscriminatorMapAnnotation'
+            );
+
+            foreach ($methods as $method) {
+                if ($code = $this->$method($metadata)) {
+                    $lines[] = ' * ' . $code;
+                }
+            }
+
+            if ($metadata->isMappedSuperclass) {
+                $lines[] = ' * @' . $this->_annotationsPrefix . 'MappedSuperClass';
+            } else {
+                $lines[] = ' * @' . $this->_annotationsPrefix . 'Entity';
+            }
+
+            if ($metadata->customRepositoryClassName) {
+                $lines[count($lines) - 1] .= '(repositoryClass="' . $metadata->customRepositoryClassName . '")';
+            }
+
+            if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
+                $lines[] = ' * @' . $this->_annotationsPrefix . 'HasLifecycleCallbacks';
+            }
+        }
+
+        $lines[] = ' */';
+
+        return implode("\n", $lines);
+    }
+
+    private function _generateTableAnnotation($metadata)
+    {
+        $table = array();
+
+        if (isset($metadata->table['schema'])) {
+            $table[] = 'schema="' . $metadata->table['schema'] . '"';
+        }
+
+        if (isset($metadata->table['name'])) {
+            $table[] = 'name="' . $metadata->table['name'] . '"';
+        }
+
+        if (isset($metadata->table['uniqueConstraints']) && $metadata->table['uniqueConstraints']) {
+            $constraints = $this->_generateTableConstraints('UniqueConstraint', $metadata->table['uniqueConstraints']);
+            $table[] = 'uniqueConstraints={' . $constraints . '}';
+        }
+
+        if (isset($metadata->table['indexes']) && $metadata->table['indexes']) {
+            $constraints = $this->_generateTableConstraints('Index', $metadata->table['indexes']);
+            $table[] = 'indexes={' . $constraints . '}';
+        }
+
+        return '@' . $this->_annotationsPrefix . 'Table(' . implode(', ', $table) . ')';
+    }
+
+    private function _generateTableConstraints($constraintName, $constraints)
+    {
+        $annotations = array();
+        foreach ($constraints as $name => $constraint) {
+            $columns = array();
+            foreach ($constraint['columns'] as $column) {
+                $columns[] = '"' . $column . '"';
+            }
+            $annotations[] = '@' . $this->_annotationsPrefix . $constraintName . '(name="' . $name . '", columns={' . implode(', ', $columns) . '})';
+        }
+        return implode(', ', $annotations);
+    }
+
+    private function _generateInheritanceAnnotation($metadata)
+    {
+        if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
+            return '@' . $this->_annotationsPrefix . 'InheritanceType("'.$this->_getInheritanceTypeString($metadata->inheritanceType).'")';
+        }
+    }
+
+    private function _generateDiscriminatorColumnAnnotation($metadata)
+    {
+        if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
+            $discrColumn = $metadata->discriminatorValue;
+            $columnDefinition = 'name="' . $discrColumn['name']
+                . '", type="' . $discrColumn['type']
+                . '", length=' . $discrColumn['length'];
+
+            return '@' . $this->_annotationsPrefix . 'DiscriminatorColumn(' . $columnDefinition . ')';
+        }
+    }
+
+    private function _generateDiscriminatorMapAnnotation($metadata)
+    {
+        if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
+            $inheritanceClassMap = array();
+
+            foreach ($metadata->discriminatorMap as $type => $class) {
+                $inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
+            }
+
+            return '@' . $this->_annotationsPrefix . 'DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
+        }
+    }
+
+    private function _generateEntityStubMethods(ClassMetadataInfo $metadata)
+    {
+        $methods = array();
+
+        foreach ($metadata->fieldMappings as $fieldMapping) {
+            if ( ! isset($fieldMapping['id']) || ! $fieldMapping['id'] || $metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE) {
+                if ($code = $this->_generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
+                    $methods[] = $code;
+                }
+            }
+
+            if ($code = $this->_generateEntityStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) {
+                $methods[] = $code;
+            }
+        }
+
+        foreach ($metadata->associationMappings as $associationMapping) {
+            if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
+                $nullable = $this->_isAssociationIsNullable($associationMapping) ? 'null' : null;
+                if ($code = $this->_generateEntityStubMethod($metadata, 'set', $associationMapping['fieldName'], $associationMapping['targetEntity'], $nullable)) {
+                    $methods[] = $code;
+                }
+                if ($code = $this->_generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
+                    $methods[] = $code;
+                }
+            } else if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
+                if ($code = $this->_generateEntityStubMethod($metadata, 'add', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
+                    $methods[] = $code;
+                }
+                if ($code = $this->_generateEntityStubMethod($metadata, 'remove', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
+                    $methods[] = $code;
+                }
+                if ($code = $this->_generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], 'Doctrine\Common\Collections\Collection')) {
+                    $methods[] = $code;
+                }
+            }
+        }
+
+        return implode("\n\n", $methods);
+    }
+
+    private function _isAssociationIsNullable($associationMapping)
+    {
+        if (isset($associationMapping['id']) && $associationMapping['id']) {
+            return false;
+        }
+        if (isset($associationMapping['joinColumns'])) {
+            $joinColumns = $associationMapping['joinColumns'];
+        } else {
+            //@todo thereis no way to retreive targetEntity metadata
+            $joinColumns = array();
+        }
+        foreach ($joinColumns as $joinColumn) {
+            if(isset($joinColumn['nullable']) && !$joinColumn['nullable']) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private function _generateEntityLifecycleCallbackMethods(ClassMetadataInfo $metadata)
+    {
+        if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
+            $methods = array();
+
+            foreach ($metadata->lifecycleCallbacks as $name => $callbacks) {
+                foreach ($callbacks as $callback) {
+                    if ($code = $this->_generateLifecycleCallbackMethod($name, $callback, $metadata)) {
+                        $methods[] = $code;
+                    }
+                }
+            }
+
+            return implode("\n\n", $methods);
+        }
+
+        return "";
+    }
+
+    private function _generateEntityAssociationMappingProperties(ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+
+        foreach ($metadata->associationMappings as $associationMapping) {
+            if ($this->_hasProperty($associationMapping['fieldName'], $metadata)) {
+                continue;
+            }
+
+            $lines[] = $this->_generateAssociationMappingPropertyDocBlock($associationMapping, $metadata);
+            $lines[] = $this->_spaces . 'private $' . $associationMapping['fieldName']
+                     . ($associationMapping['type'] == 'manyToMany' ? ' = array()' : null) . ";\n";
+        }
+
+        return implode("\n", $lines);
+    }
+
+    private function _generateEntityFieldMappingProperties(ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+
+        foreach ($metadata->fieldMappings as $fieldMapping) {
+            if ($this->_hasProperty($fieldMapping['fieldName'], $metadata) ||
+                $metadata->isInheritedField($fieldMapping['fieldName'])) {
+                continue;
+            }
+
+            $lines[] = $this->_generateFieldMappingPropertyDocBlock($fieldMapping, $metadata);
+            $lines[] = $this->_spaces . 'private $' . $fieldMapping['fieldName']
+                     . (isset($fieldMapping['default']) ? ' = ' . var_export($fieldMapping['default'], true) : null) . ";\n";
+        }
+
+        return implode("\n", $lines);
+    }
+
+    private function _generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null,  $defaultValue = null)
+    {
+        $methodName = $type . Inflector::classify($fieldName);
+        if (in_array($type, array("add", "remove")) && substr($methodName, -1) == "s") {
+            $methodName = substr($methodName, 0, -1);
+        }
+
+        if ($this->_hasMethod($methodName, $metadata)) {
+            return;
+        }
+        $this->_staticReflection[$metadata->name]['methods'][] = $methodName;
+
+        $var = sprintf('_%sMethodTemplate', $type);
+        $template = self::$$var;
+
+        $variableType = $typeHint ? $typeHint . ' ' : null;
+
+        $types = \Doctrine\DBAL\Types\Type::getTypesMap();
+        $methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
+
+        $replacements = array(
+          '<description>'       => ucfirst($type) . ' ' . $fieldName,
+          '<methodTypeHint>'    => $methodTypeHint,
+          '<variableType>'      => $variableType,
+          '<variableName>'      => Inflector::camelize($fieldName),
+          '<methodName>'        => $methodName,
+          '<fieldName>'         => $fieldName,
+          '<variableDefault>'   => ($defaultValue !== null ) ? (' = '.$defaultValue) : '',
+          '<entity>'            => $this->_getClassName($metadata)
+        );
+
+        $method = str_replace(
+            array_keys($replacements),
+            array_values($replacements),
+            $template
+        );
+
+        return $this->_prefixCodeWithSpaces($method);
+    }
+
+    private function _generateLifecycleCallbackMethod($name, $methodName, $metadata)
+    {
+        if ($this->_hasMethod($methodName, $metadata)) {
+            return;
+        }
+        $this->_staticReflection[$metadata->name]['methods'][] = $methodName;
+
+        $replacements = array(
+            '<name>'        => $this->_annotationsPrefix . ucfirst($name),
+            '<methodName>'  => $methodName,
+        );
+
+        $method = str_replace(
+            array_keys($replacements),
+            array_values($replacements),
+            self::$_lifecycleCallbackMethodTemplate
+        );
+
+        return $this->_prefixCodeWithSpaces($method);
+    }
+
+    private function _generateJoinColumnAnnotation(array $joinColumn)
+    {
+        $joinColumnAnnot = array();
+
+        if (isset($joinColumn['name'])) {
+            $joinColumnAnnot[] = 'name="' . $joinColumn['name'] . '"';
+        }
+
+        if (isset($joinColumn['referencedColumnName'])) {
+            $joinColumnAnnot[] = 'referencedColumnName="' . $joinColumn['referencedColumnName'] . '"';
+        }
+
+        if (isset($joinColumn['unique']) && $joinColumn['unique']) {
+            $joinColumnAnnot[] = 'unique=' . ($joinColumn['unique'] ? 'true' : 'false');
+        }
+
+        if (isset($joinColumn['nullable'])) {
+            $joinColumnAnnot[] = 'nullable=' . ($joinColumn['nullable'] ? 'true' : 'false');
+        }
+
+        if (isset($joinColumn['onDelete'])) {
+            $joinColumnAnnot[] = 'onDelete="' . ($joinColumn['onDelete'] . '"');
+        }
+
+        if (isset($joinColumn['columnDefinition'])) {
+            $joinColumnAnnot[] = 'columnDefinition="' . $joinColumn['columnDefinition'] . '"';
+        }
+
+        return '@' . $this->_annotationsPrefix . 'JoinColumn(' . implode(', ', $joinColumnAnnot) . ')';
+    }
+
+    private function _generateAssociationMappingPropertyDocBlock(array $associationMapping, ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+        $lines[] = $this->_spaces . '/**';
+
+        if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
+            $lines[] = $this->_spaces . ' * @var \Doctrine\Common\Collections\ArrayCollection';
+        } else {
+            $lines[] = $this->_spaces . ' * @var ' . $associationMapping['targetEntity'];
+        }
+
+        if ($this->_generateAnnotations) {
+            $lines[] = $this->_spaces . ' *';
+            
+            if (isset($associationMapping['id']) && $associationMapping['id']) {
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Id';
+            
+                if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+                    $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")';
+                }
+            }
+
+            $type = null;
+            switch ($associationMapping['type']) {
+                case ClassMetadataInfo::ONE_TO_ONE:
+                    $type = 'OneToOne';
+                    break;
+                case ClassMetadataInfo::MANY_TO_ONE:
+                    $type = 'ManyToOne';
+                    break;
+                case ClassMetadataInfo::ONE_TO_MANY:
+                    $type = 'OneToMany';
+                    break;
+                case ClassMetadataInfo::MANY_TO_MANY:
+                    $type = 'ManyToMany';
+                    break;
+            }
+            $typeOptions = array();
+
+            if (isset($associationMapping['targetEntity'])) {
+                $typeOptions[] = 'targetEntity="' . $associationMapping['targetEntity'] . '"';
+            }
+
+            if (isset($associationMapping['inversedBy'])) {
+                $typeOptions[] = 'inversedBy="' . $associationMapping['inversedBy'] . '"';
+            }
+
+            if (isset($associationMapping['mappedBy'])) {
+                $typeOptions[] = 'mappedBy="' . $associationMapping['mappedBy'] . '"';
+            }
+
+            if ($associationMapping['cascade']) {
+                $cascades = array();
+
+                if ($associationMapping['isCascadePersist']) $cascades[] = '"persist"';
+                if ($associationMapping['isCascadeRemove']) $cascades[] = '"remove"';
+                if ($associationMapping['isCascadeDetach']) $cascades[] = '"detach"';
+                if ($associationMapping['isCascadeMerge']) $cascades[] = '"merge"';
+                if ($associationMapping['isCascadeRefresh']) $cascades[] = '"refresh"';
+
+                $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
+            }
+
+            if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval']) {
+                $typeOptions[] = 'orphanRemoval=' . ($associationMapping['orphanRemoval'] ? 'true' : 'false');
+            }
+
+            $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . '' . $type . '(' . implode(', ', $typeOptions) . ')';
+
+            if (isset($associationMapping['joinColumns']) && $associationMapping['joinColumns']) {
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'JoinColumns({';
+
+                $joinColumnsLines = array();
+
+                foreach ($associationMapping['joinColumns'] as $joinColumn) {
+                    if ($joinColumnAnnot = $this->_generateJoinColumnAnnotation($joinColumn)) {
+                        $joinColumnsLines[] = $this->_spaces . ' *   ' . $joinColumnAnnot;
+                    }
+                }
+
+                $lines[] = implode(",\n", $joinColumnsLines);
+                $lines[] = $this->_spaces . ' * })';
+            }
+
+            if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
+                $joinTable = array();
+                $joinTable[] = 'name="' . $associationMapping['joinTable']['name'] . '"';
+
+                if (isset($associationMapping['joinTable']['schema'])) {
+                    $joinTable[] = 'schema="' . $associationMapping['joinTable']['schema'] . '"';
+                }
+
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'JoinTable(' . implode(', ', $joinTable) . ',';
+                $lines[] = $this->_spaces . ' *   joinColumns={';
+
+                foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
+                    $lines[] = $this->_spaces . ' *     ' . $this->_generateJoinColumnAnnotation($joinColumn);
+                }
+
+                $lines[] = $this->_spaces . ' *   },';
+                $lines[] = $this->_spaces . ' *   inverseJoinColumns={';
+
+                foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
+                    $lines[] = $this->_spaces . ' *     ' . $this->_generateJoinColumnAnnotation($joinColumn);
+                }
+
+                $lines[] = $this->_spaces . ' *   }';
+                $lines[] = $this->_spaces . ' * )';
+            }
+
+            if (isset($associationMapping['orderBy'])) {
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'OrderBy({';
+
+                foreach ($associationMapping['orderBy'] as $name => $direction) {
+                    $lines[] = $this->_spaces . ' *     "' . $name . '"="' . $direction . '",';
+                }
+
+                $lines[count($lines) - 1] = substr($lines[count($lines) - 1], 0, strlen($lines[count($lines) - 1]) - 1);
+                $lines[] = $this->_spaces . ' * })';
+            }
+        }
+
+        $lines[] = $this->_spaces . ' */';
+
+        return implode("\n", $lines);
+    }
+
+    private function _generateFieldMappingPropertyDocBlock(array $fieldMapping, ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+        $lines[] = $this->_spaces . '/**';
+        $lines[] = $this->_spaces . ' * @var ' . $fieldMapping['type'] . ' $' . $fieldMapping['fieldName'];
+
+        if ($this->_generateAnnotations) {
+            $lines[] = $this->_spaces . ' *';
+
+            $column = array();
+            if (isset($fieldMapping['columnName'])) {
+                $column[] = 'name="' . $fieldMapping['columnName'] . '"';
+            }
+
+            if (isset($fieldMapping['type'])) {
+                $column[] = 'type="' . $fieldMapping['type'] . '"';
+            }
+
+            if (isset($fieldMapping['length'])) {
+                $column[] = 'length=' . $fieldMapping['length'];
+            }
+
+            if (isset($fieldMapping['precision'])) {
+                $column[] = 'precision=' .  $fieldMapping['precision'];
+            }
+
+            if (isset($fieldMapping['scale'])) {
+                $column[] = 'scale=' . $fieldMapping['scale'];
+            }
+
+            if (isset($fieldMapping['nullable'])) {
+                $column[] = 'nullable=' .  var_export($fieldMapping['nullable'], true);
+            }
+
+            if (isset($fieldMapping['columnDefinition'])) {
+                $column[] = 'columnDefinition="' . $fieldMapping['columnDefinition'] . '"';
+            }
+
+            if (isset($fieldMapping['unique'])) {
+                $column[] = 'unique=' . var_export($fieldMapping['unique'], true);
+            }
+
+            $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Column(' . implode(', ', $column) . ')';
+
+            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Id';
+
+                if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+                    $lines[] = $this->_spaces.' * @' . $this->_annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")';
+                }
+
+                if ($metadata->sequenceGeneratorDefinition) {
+                    $sequenceGenerator = array();
+
+                    if (isset($metadata->sequenceGeneratorDefinition['sequenceName'])) {
+                        $sequenceGenerator[] = 'sequenceName="' . $metadata->sequenceGeneratorDefinition['sequenceName'] . '"';
+                    }
+
+                    if (isset($metadata->sequenceGeneratorDefinition['allocationSize'])) {
+                        $sequenceGenerator[] = 'allocationSize=' . $metadata->sequenceGeneratorDefinition['allocationSize'];
+                    }
+
+                    if (isset($metadata->sequenceGeneratorDefinition['initialValue'])) {
+                        $sequenceGenerator[] = 'initialValue=' . $metadata->sequenceGeneratorDefinition['initialValue'];
+                    }
+
+                    $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'SequenceGenerator(' . implode(', ', $sequenceGenerator) . ')';
+                }
+            }
+
+            if (isset($fieldMapping['version']) && $fieldMapping['version']) {
+                $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Version';
+            }
+        }
+
+        $lines[] = $this->_spaces . ' */';
+
+        return implode("\n", $lines);
+    }
+
+    private function _prefixCodeWithSpaces($code, $num = 1)
+    {
+        $lines = explode("\n", $code);
+
+        foreach ($lines as $key => $value) {
+            $lines[$key] = str_repeat($this->_spaces, $num) . $lines[$key];
+        }
+
+        return implode("\n", $lines);
+    }
+
+    private function _getInheritanceTypeString($type)
+    {
+        switch ($type) {
+            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
+                return 'NONE';
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
+                return 'JOINED';
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
+                return 'SINGLE_TABLE';
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
+                return 'PER_CLASS';
+
+            default:
+                throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
+        }
+    }
+
+    private function _getChangeTrackingPolicyString($policy)
+    {
+        switch ($policy) {
+            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
+                return 'DEFERRED_IMPLICIT';
+
+            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
+                return 'DEFERRED_EXPLICIT';
+
+            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
+                return 'NOTIFY';
+
+            default:
+                throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
+        }
+    }
+
+    private function _getIdGeneratorTypeString($type)
+    {
+        switch ($type) {
+            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
+                return 'AUTO';
+
+            case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
+                return 'SEQUENCE';
+
+            case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
+                return 'TABLE';
+
+            case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
+                return 'IDENTITY';
+
+            case ClassMetadataInfo::GENERATOR_TYPE_NONE:
+                return 'NONE';
+
+            default:
+                throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityRepositoryGenerator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityRepositoryGenerator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/EntityRepositoryGenerator.php	(revision 345)
@@ -0,0 +1,83 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+/**
+ * Class to generate entity repository classes
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EntityRepositoryGenerator
+{
+    protected static $_template =
+'<?php
+
+namespace <namespace>;
+
+use Doctrine\ORM\EntityRepository;
+
+/**
+ * <className>
+ *
+ * This class was generated by the Doctrine ORM. Add your own custom
+ * repository methods below.
+ */
+class <className> extends EntityRepository
+{
+}';
+
+    public function generateEntityRepositoryClass($fullClassName)
+    {
+        $namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\'));
+        $className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName));
+
+        $variables = array(
+            '<namespace>' => $namespace,
+            '<className>' => $className
+        );
+        return str_replace(array_keys($variables), array_values($variables), self::$_template);
+    }
+
+    public function writeEntityRepositoryClass($fullClassName, $outputDirectory)
+    {
+        $code = $this->generateEntityRepositoryClass($fullClassName);
+
+        $path = $outputDirectory . DIRECTORY_SEPARATOR
+              . str_replace('\\', \DIRECTORY_SEPARATOR, $fullClassName) . '.php';
+        $dir = dirname($path);
+
+        if ( ! is_dir($dir)) {
+            mkdir($dir, 0777, true);
+        }
+
+        if ( ! file_exists($path)) {
+            file_put_contents($path, $code);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php	(revision 345)
@@ -0,0 +1,65 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools\Event;
+
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Event Args used for the Events::postGenerateSchema event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class GenerateSchemaEventArgs extends \Doctrine\Common\EventArgs
+{
+    private $_em = null;
+    private $_schema = null;
+
+    /**
+     * @param ClassMetadata $classMetadata
+     * @param Schema $schema
+     * @param Table $classTable
+     */
+    public function __construct(EntityManager $em, Schema $schema)
+    {
+        $this->_em = $em;
+        $this->_schema = $schema;
+    }
+
+    /**
+     * @return EntityManager
+     */
+    public function getEntityManager() {
+        return $this->_em;
+    }
+
+    /**
+     * @return Schema
+     */
+    public function getSchema() {
+        return $this->_schema;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php	(revision 345)
@@ -0,0 +1,75 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools\Event;
+
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Schema\Table;
+
+/**
+ * Event Args used for the Events::postGenerateSchemaTable event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class GenerateSchemaTableEventArgs extends \Doctrine\Common\EventArgs
+{
+    private $_classMetadata = null;
+    private $_schema = null;
+    private $_classTable = null;
+
+    /**
+     * @param ClassMetadata $classMetadata
+     * @param Schema $schema
+     * @param Table $classTable
+     */
+    public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable)
+    {
+        $this->_classMetadata = $classMetadata;
+        $this->_schema = $schema;
+        $this->_classTable = $classTable;
+    }
+
+    /**
+     * @return ClassMetadata
+     */
+    public function getClassMetadata() {
+        return $this->_classMetadata;
+    }
+
+    /**
+     * @return Schema
+     */
+    public function getSchema() {
+        return $this->_schema;
+    }
+
+    /**
+     * @return Table
+     */
+    public function getClassTable() {
+        return $this->_classTable;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export;
+
+use Doctrine\ORM\Tools\Export\ExportException,
+    Doctrine\ORM\EntityManager;
+
+/**
+ * Class used for converting your mapping information between the
+ * supported formats: yaml, xml, and php/annotation.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+class ClassMetadataExporter
+{
+    private static $_exporterDrivers = array(
+        'xml' => 'Doctrine\ORM\Tools\Export\Driver\XmlExporter',
+        'yaml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
+        'yml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
+        'php' => 'Doctrine\ORM\Tools\Export\Driver\PhpExporter',
+        'annotation' => 'Doctrine\ORM\Tools\Export\Driver\AnnotationExporter'
+    );
+
+    /**
+     * Register a new exporter driver class under a specified name
+     *
+     * @param string $name
+     * @param string $class
+     */
+    public static function registerExportDriver($name, $class)
+    {
+        self::$_exporterDrivers[$name] = $class;
+    }
+
+    /**
+     * Get a exporter driver instance
+     *
+     * @param string $type   The type to get (yml, xml, etc.)
+     * @param string $source    The directory where the exporter will export to
+     * @return AbstractExporter $exporter
+     */
+    public function getExporter($type, $dest = null)
+    {
+        if ( ! isset(self::$_exporterDrivers[$type])) {
+            throw ExportException::invalidExporterDriverType($type);
+        }
+
+        $class = self::$_exporterDrivers[$type];
+
+        return new $class($dest);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php	(revision 345)
@@ -0,0 +1,217 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\ORM\Tools\Export\ExportException;
+
+/**
+ * Abstract base class which is to be used for the Exporter drivers
+ * which can be found in \Doctrine\ORM\Tools\Export\Driver
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+abstract class AbstractExporter
+{
+    protected $_metadata = array();
+    protected $_outputDir;
+    protected $_extension;
+    protected $_overwriteExistingFiles = false;
+
+    public function __construct($dir = null)
+    {
+        $this->_outputDir = $dir;
+    }
+
+    public function setOverwriteExistingFiles($overwrite)
+    {
+        $this->_overwriteExistingFiles = $overwrite;
+    }
+
+    /**
+     * Converts a single ClassMetadata instance to the exported format
+     * and returns it
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return mixed $exported
+     */
+    abstract public function exportClassMetadata(ClassMetadataInfo $metadata);
+
+    /**
+     * Set the array of ClassMetadataInfo instances to export
+     *
+     * @param array $metadata
+     * @return void
+     */
+    public function setMetadata(array $metadata)
+    {
+        $this->_metadata = $metadata;
+    }
+
+    /**
+     * Get the extension used to generated the path to a class
+     *
+     * @return string $extension
+     */
+    public function getExtension()
+    {
+        return $this->_extension;
+    }
+
+    /**
+     * Set the directory to output the mapping files to
+     *
+     *     [php]
+     *     $exporter = new YamlExporter($metadata);
+     *     $exporter->setOutputDir(__DIR__ . '/yaml');
+     *     $exporter->export();
+     *
+     * @param string $dir
+     * @return void
+     */
+    public function setOutputDir($dir)
+    {
+        $this->_outputDir = $dir;
+    }
+
+    /**
+     * Export each ClassMetadata instance to a single Doctrine Mapping file
+     * named after the entity
+     *
+     * @return void
+     */
+    public function export()
+    {
+        if ( ! is_dir($this->_outputDir)) {
+            mkdir($this->_outputDir, 0777, true);
+        }
+
+        foreach ($this->_metadata as $metadata) {
+            //In case output is returned, write it to a file, skip otherwise
+            if($output = $this->exportClassMetadata($metadata)){
+                $path = $this->_generateOutputPath($metadata);
+                $dir = dirname($path);
+                if ( ! is_dir($dir)) {
+                    mkdir($dir, 0777, true);
+                }
+                if (file_exists($path) && !$this->_overwriteExistingFiles) {
+                    throw ExportException::attemptOverwriteExistingFile($path);
+                }
+                file_put_contents($path, $output);
+            }
+        }
+    }
+
+    /**
+     * Generate the path to write the class for the given ClassMetadataInfo instance
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return string $path
+     */
+    protected function _generateOutputPath(ClassMetadataInfo $metadata)
+    {
+        return $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension;
+    }
+
+    /**
+     * Set the directory to output the mapping files to
+     *
+     *     [php]
+     *     $exporter = new YamlExporter($metadata, __DIR__ . '/yaml');
+     *     $exporter->setExtension('.yml');
+     *     $exporter->export();
+     *
+     * @param string $extension
+     * @return void
+     */
+    public function setExtension($extension)
+    {
+        $this->_extension = $extension;
+    }
+
+    protected function _getInheritanceTypeString($type)
+    {
+        switch ($type)
+        {
+            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
+                return 'NONE';
+            break;
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
+                return 'JOINED';
+            break;
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
+                return 'SINGLE_TABLE';
+            break;
+
+            case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
+                return 'PER_CLASS';
+            break;
+        }
+    }
+
+    protected function _getChangeTrackingPolicyString($policy)
+    {
+        switch ($policy)
+        {
+            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
+                return 'DEFERRED_IMPLICIT';
+            break;
+
+            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
+                return 'DEFERRED_EXPLICIT';
+            break;
+
+            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
+                return 'NOTIFY';
+            break;
+        }
+    }
+
+    protected function _getIdGeneratorTypeString($type)
+    {
+        switch ($type)
+        {
+            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
+                return 'AUTO';
+            break;
+
+            case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
+                return 'SEQUENCE';
+            break;
+
+            case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
+                return 'TABLE';
+            break;
+
+            case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
+                return 'IDENTITY';
+            break;
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php	(revision 345)
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo,
+    Doctrine\ORM\Tools\EntityGenerator;
+
+/**
+ * ClassMetadata exporter for PHP classes with annotations
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+class AnnotationExporter extends AbstractExporter
+{
+    protected $_extension = '.php';
+    private $_entityGenerator;
+
+    /**
+     * Converts a single ClassMetadata instance to the exported format
+     * and returns it
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return string $exported
+     */
+    public function exportClassMetadata(ClassMetadataInfo $metadata)
+    {
+        if ( ! $this->_entityGenerator) {
+            throw new \RuntimeException('For the AnnotationExporter you must set an EntityGenerator instance with the setEntityGenerator() method.');
+        }
+        $this->_entityGenerator->setGenerateAnnotations(true);
+        $this->_entityGenerator->setGenerateStubMethods(false);
+        $this->_entityGenerator->setRegenerateEntityIfExists(false);
+        $this->_entityGenerator->setUpdateEntityIfExists(false);
+
+        return $this->_entityGenerator->generateEntityClass($metadata);
+    }
+
+    protected function _generateOutputPath(ClassMetadataInfo $metadata)
+    {
+        return $this->_outputDir . '/' . str_replace('\\', '/', $metadata->name) . $this->_extension;
+    }
+
+    public function setEntityGenerator(EntityGenerator $entityGenerator)
+    {
+        $this->_entityGenerator = $entityGenerator;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php	(revision 345)
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * ClassMetadata exporter for PHP code
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+class PhpExporter extends AbstractExporter
+{
+    protected $_extension = '.php';
+
+    /**
+     * Converts a single ClassMetadata instance to the exported format
+     * and returns it
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return mixed $exported
+     */
+    public function exportClassMetadata(ClassMetadataInfo $metadata)
+    {
+        $lines = array();
+        $lines[] = '<?php';
+        $lines[] = null;
+        $lines[] = 'use Doctrine\ORM\Mapping\ClassMetadataInfo;';
+        $lines[] = null;
+
+        if ($metadata->isMappedSuperclass) {
+            $lines[] = '$metadata->isMappedSuperclass = true;';
+        }
+
+        if ($metadata->inheritanceType) {
+            $lines[] = '$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');';
+        }
+
+        if ($metadata->customRepositoryClassName) {
+            $lines[] = "\$metadata->customRepositoryClassName = '" . $metadata->customRepositoryClassName . "';";
+        }
+
+        if ($metadata->table) {
+            $lines[] = '$metadata->setPrimaryTable(' . $this->_varExport($metadata->table) . ');';
+        }
+
+        if ($metadata->discriminatorColumn) {
+            $lines[] = '$metadata->setDiscriminatorColumn(' . $this->_varExport($metadata->discriminatorColumn) . ');';
+        }
+
+        if ($metadata->discriminatorMap) {
+            $lines[] = '$metadata->setDiscriminatorMap(' . $this->_varExport($metadata->discriminatorMap) . ');';
+        }
+
+        if ($metadata->changeTrackingPolicy) {
+            $lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');';
+        }
+
+        if ($metadata->lifecycleCallbacks) {
+            foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
+                foreach ($callbacks as $callback) {
+                    $lines[] = "\$metadata->addLifecycleCallback('$callback', '$event');";
+                }
+            }
+        }
+
+        foreach ($metadata->fieldMappings as $fieldMapping) {
+            $lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');';
+        }
+
+        if ( ! $metadata->isIdentifierComposite && $generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+            $lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');';
+        }
+
+        foreach ($metadata->associationMappings as $associationMapping) {
+            $cascade = array('remove', 'persist', 'refresh', 'merge', 'detach');
+            foreach ($cascade as $key => $value) {
+                if ( ! $associationMapping['isCascade'.ucfirst($value)]) {
+                    unset($cascade[$key]);
+                }
+            }
+            $associationMappingArray = array(
+                'fieldName'    => $associationMapping['fieldName'],
+                'targetEntity' => $associationMapping['targetEntity'],
+                'cascade'     => $cascade,
+            );
+
+            if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
+                $method = 'mapOneToOne';
+                $oneToOneMappingArray = array(
+                    'mappedBy'      => $associationMapping['mappedBy'],
+                    'inversedBy'    => $associationMapping['inversedBy'],
+                    'joinColumns'   => $associationMapping['joinColumns'],
+                    'orphanRemoval' => $associationMapping['orphanRemoval'],
+                );
+
+                $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
+            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
+                $method = 'mapOneToMany';
+                $potentialAssociationMappingIndexes = array(
+                    'mappedBy',
+                    'orphanRemoval',
+                    'orderBy',
+                );
+                foreach ($potentialAssociationMappingIndexes as $index) {
+                    if (isset($associationMapping[$index])) {
+                        $oneToManyMappingArray[$index] = $associationMapping[$index];
+                    }
+                }
+                $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
+            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
+                $method = 'mapManyToMany';
+                $potentialAssociationMappingIndexes = array(
+                    'mappedBy',
+                    'joinTable',
+                    'orderBy',
+                );
+                foreach ($potentialAssociationMappingIndexes as $index) {
+                    if (isset($associationMapping[$index])) {
+                        $manyToManyMappingArray[$index] = $associationMapping[$index];
+                    }
+                }
+                $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
+            }
+
+            $lines[] = '$metadata->' . $method . '(' . $this->_varExport($associationMappingArray) . ');';
+        }
+
+        return implode("\n", $lines);
+    }
+
+    protected function _varExport($var)
+    {
+        $export = var_export($var, true);
+        $export = str_replace("\n", PHP_EOL . str_repeat(' ', 8), $export);
+        $export = str_replace('  ', ' ', $export);
+        $export = str_replace('array (', 'array(', $export);
+        $export = str_replace('array( ', 'array(', $export);
+        $export = str_replace(',)', ')', $export);
+        $export = str_replace(', )', ')', $export);
+        $export = str_replace('  ', ' ', $export);
+
+        return $export;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php	(revision 345)
@@ -0,0 +1,320 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * ClassMetadata exporter for Doctrine XML mapping files
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+class XmlExporter extends AbstractExporter
+{
+    protected $_extension = '.dcm.xml';
+
+    /**
+     * Converts a single ClassMetadata instance to the exported format
+     * and returns it
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return mixed $exported
+     */
+    public function exportClassMetadata(ClassMetadataInfo $metadata)
+    {
+        $xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping ".
+            "xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " .
+            "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
+            "xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />");
+
+        /*$xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping');
+        $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+        $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd');*/
+
+        if ($metadata->isMappedSuperclass) {
+            $root = $xml->addChild('mapped-superclass');
+        } else {
+            $root = $xml->addChild('entity');
+        }
+
+        if ($metadata->customRepositoryClassName) {
+            $root->addAttribute('repository-class', $metadata->customRepositoryClassName);
+        }
+
+        $root->addAttribute('name', $metadata->name);
+
+        if (isset($metadata->table['name'])) {
+            $root->addAttribute('table', $metadata->table['name']);
+        }
+
+        if (isset($metadata->table['schema'])) {
+            $root->addAttribute('schema', $metadata->table['schema']);
+        }
+
+        if (isset($metadata->table['inheritance-type'])) {
+            $root->addAttribute('inheritance-type', $metadata->table['inheritance-type']);
+        }
+
+        if ($metadata->discriminatorColumn) {
+            $discriminatorColumnXml = $root->addChild('discriminiator-column');
+            $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
+            $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
+            $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
+        }
+
+        if ($metadata->discriminatorMap) {
+            $discriminatorMapXml = $root->addChild('discriminator-map');
+            foreach ($metadata->discriminatorMap as $value => $className) {
+                $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
+                $discriminatorMappingXml->addAttribute('value', $value);
+                $discriminatorMappingXml->addAttribute('class', $className);
+            }
+        }
+
+        $root->addChild('change-tracking-policy', $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy));
+
+        if (isset($metadata->table['indexes'])) {
+            $indexesXml = $root->addChild('indexes');
+
+            foreach ($metadata->table['indexes'] as $name => $index) {
+                $indexXml = $indexesXml->addChild('index');
+                $indexXml->addAttribute('name', $name);
+                $indexXml->addAttribute('columns', implode(',', $index['columns']));
+            }
+        }
+
+        if (isset($metadata->table['uniqueConstraints'])) {
+            $uniqueConstraintsXml = $root->addChild('unique-constraints');
+
+            foreach ($metadata->table['uniqueConstraints'] as $unique) {
+                $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
+                $uniqueConstraintXml->addAttribute('name', $unique['name']);
+                $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
+            }
+        }
+
+        $fields = $metadata->fieldMappings;
+
+        $id = array();
+        foreach ($fields as $name => $field) {
+            if (isset($field['id']) && $field['id']) {
+                $id[$name] = $field;
+                unset($fields[$name]);
+            }
+        }
+
+        if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+            $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
+        }
+
+        if ($id) {
+            foreach ($id as $field) {
+                $idXml = $root->addChild('id');
+                $idXml->addAttribute('name', $field['fieldName']);
+                $idXml->addAttribute('type', $field['type']);
+                if (isset($field['columnName'])) {
+                    $idXml->addAttribute('column', $field['columnName']);
+                }
+                if (isset($field['associationKey']) && $field['associationKey']) {
+                    $idXml->addAttribute('association-key', 'true');
+                }
+                if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+                    $generatorXml = $idXml->addChild('generator');
+                    $generatorXml->addAttribute('strategy', $idGeneratorType);
+                }
+            }
+        }
+
+        if ($fields) {
+            foreach ($fields as $field) {
+                $fieldXml = $root->addChild('field');
+                $fieldXml->addAttribute('name', $field['fieldName']);
+                $fieldXml->addAttribute('type', $field['type']);
+                if (isset($field['columnName'])) {
+                    $fieldXml->addAttribute('column', $field['columnName']);
+                }
+                if (isset($field['length'])) {
+                    $fieldXml->addAttribute('length', $field['length']);
+                }
+                if (isset($field['precision'])) {
+                    $fieldXml->addAttribute('precision', $field['precision']);
+                }
+                if (isset($field['scale'])) {
+                    $fieldXml->addAttribute('scale', $field['scale']);
+                }
+                if (isset($field['unique']) && $field['unique']) {
+                    $fieldXml->addAttribute('unique', $field['unique']);
+                }
+                if (isset($field['options'])) {
+                    $optionsXml = $fieldXml->addChild('options');
+                    foreach ($field['options'] as $key => $value) {
+                        $optionsXml->addAttribute($key, $value);
+                    }
+                }
+                if (isset($field['version'])) {
+                    $fieldXml->addAttribute('version', $field['version']);
+                }
+                if (isset($field['columnDefinition'])) {
+                    $fieldXml->addAttribute('column-definition', $field['columnDefinition']);
+                }
+            }
+        }
+
+        foreach ($metadata->associationMappings as $name => $associationMapping) {
+            if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) {
+                $associationMappingXml = $root->addChild('one-to-one');
+            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
+                $associationMappingXml = $root->addChild('many-to-one');
+            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
+                $associationMappingXml = $root->addChild('one-to-many');
+            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
+                $associationMappingXml = $root->addChild('many-to-many');
+            }
+
+            $associationMappingXml->addAttribute('field', $associationMapping['fieldName']);
+            $associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']);
+
+            if (isset($associationMapping['mappedBy'])) {
+                $associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']);
+            }
+            if (isset($associationMapping['inversedBy'])) {
+                $associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']);
+            }
+            if (isset($associationMapping['orphanRemoval'])) {
+                $associationMappingXml->addAttribute('orphan-removal', $associationMapping['orphanRemoval']);
+            }
+            if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
+                $joinTableXml = $associationMappingXml->addChild('join-table');
+                $joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']);
+                $joinColumnsXml = $joinTableXml->addChild('join-columns');
+                foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
+                    $joinColumnXml = $joinColumnsXml->addChild('join-column');
+                    $joinColumnXml->addAttribute('name', $joinColumn['name']);
+                    $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
+                    if (isset($joinColumn['onDelete'])) {
+                        $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
+                    }
+                }
+                $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns');
+                foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
+                    $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column');
+                    $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']);
+                    $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']);
+                    if (isset($inverseJoinColumn['onDelete'])) {
+                        $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']);
+                    }
+                    if (isset($inverseJoinColumn['columnDefinition'])) {
+                        $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']);
+                    }
+                    if (isset($inverseJoinColumn['nullable'])) {
+                        $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']);
+                    }
+                    if (isset($inverseJoinColumn['orderBy'])) {
+                        $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']);
+                    }
+                }
+            }
+            if (isset($associationMapping['joinColumns'])) {
+                $joinColumnsXml = $associationMappingXml->addChild('join-columns');
+                foreach ($associationMapping['joinColumns'] as $joinColumn) {
+                    $joinColumnXml = $joinColumnsXml->addChild('join-column');
+                    $joinColumnXml->addAttribute('name', $joinColumn['name']);
+                    $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
+                    if (isset($joinColumn['onDelete'])) {
+                        $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
+                    }
+                    if (isset($joinColumn['columnDefinition'])) {
+                        $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']);
+                    }
+                    if (isset($joinColumn['nullable'])) {
+                        $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']);
+                    }
+                }
+            }
+            if (isset($associationMapping['orderBy'])) {
+                $orderByXml = $associationMappingXml->addChild('order-by');
+                foreach ($associationMapping['orderBy'] as $name => $direction) {
+                    $orderByFieldXml = $orderByXml->addChild('order-by-field');
+                    $orderByFieldXml->addAttribute('name', $name);
+                    $orderByFieldXml->addAttribute('direction', $direction);
+                }
+            }
+            $cascade = array();
+            if ($associationMapping['isCascadeRemove']) {
+                $cascade[] = 'cascade-remove';
+            }
+            if ($associationMapping['isCascadePersist']) {
+                $cascade[] = 'cascade-persist';
+            }
+            if ($associationMapping['isCascadeRefresh']) {
+                $cascade[] = 'cascade-refresh';
+            }
+            if ($associationMapping['isCascadeMerge']) {
+                $cascade[] = 'cascade-merge';
+            }
+            if ($associationMapping['isCascadeDetach']) {
+                $cascade[] = 'cascade-detach';
+            }
+            if (count($cascade) === 5) {
+                $cascade  = array('cascade-all');
+            }
+            if ($cascade) {
+                $cascadeXml = $associationMappingXml->addChild('cascade');
+                foreach ($cascade as $type) {
+                    $cascadeXml->addChild($type);
+                }
+            }
+        }
+
+        if (isset($metadata->lifecycleCallbacks)) {
+            $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks');
+            foreach ($metadata->lifecycleCallbacks as $name => $methods) {
+                foreach ($methods as $method) {
+                    $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback');
+                    $lifecycleCallbackXml->addAttribute('type', $name);
+                    $lifecycleCallbackXml->addAttribute('method', $method);
+                }
+            }
+        }
+
+        return $this->_asXml($xml);
+    }
+
+    /**
+     * @param \SimpleXMLElement $simpleXml
+     * @return string $xml
+     */
+    private function _asXml($simpleXml)
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->loadXML($simpleXml->asXML());
+        $dom->formatOutput = true;
+
+        $result = $dom->saveXML();
+        return $result;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php	(revision 345)
@@ -0,0 +1,210 @@
+<?php
+
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Export\Driver;
+
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+/**
+ * ClassMetadata exporter for Doctrine YAML mapping files
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+class YamlExporter extends AbstractExporter
+{
+    protected $_extension = '.dcm.yml';
+
+    /**
+     * Converts a single ClassMetadata instance to the exported format
+     * and returns it
+     *
+     * TODO: Should this code be pulled out in to a toArray() method in ClassMetadata
+     *
+     * @param ClassMetadataInfo $metadata
+     * @return mixed $exported
+     */
+    public function exportClassMetadata(ClassMetadataInfo $metadata)
+    {
+        $array = array();
+
+        if ($metadata->isMappedSuperclass) {
+            $array['type'] = 'mappedSuperclass';
+        } else {
+            $array['type'] = 'entity';
+        }
+
+        $array['table'] = $metadata->table['name'];
+
+        if (isset($metadata->table['schema'])) {
+            $array['schema'] = $metadata->table['schema'];
+        }
+
+        $inheritanceType = $metadata->inheritanceType;
+        if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
+            $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
+        }
+
+        if ($column = $metadata->discriminatorColumn) {
+            $array['discriminatorColumn'] = $column;
+        }
+
+        if ($map = $metadata->discriminatorMap) {
+            $array['discriminatorMap'] = $map;
+        }
+
+        if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) {
+            $array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
+        }
+
+        if (isset($metadata->table['indexes'])) {
+            $array['indexes'] = $metadata->table['indexes'];
+        }
+
+        if ($metadata->customRepositoryClassName) {
+            $array['repositoryClass'] = $metadata->customRepositoryClassName;
+        }
+
+        if (isset($metadata->table['uniqueConstraints'])) {
+            $array['uniqueConstraints'] = $metadata->table['uniqueConstraints'];
+        }
+
+        $fieldMappings = $metadata->fieldMappings;
+
+        $ids = array();
+        foreach ($fieldMappings as $name => $fieldMapping) {
+            $fieldMapping['column'] = $fieldMapping['columnName'];
+            unset(
+                $fieldMapping['columnName'],
+                $fieldMapping['fieldName']
+            );
+
+            if ($fieldMapping['column'] == $name) {
+                unset($fieldMapping['column']);
+            }
+
+            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
+                $ids[$name] = $fieldMapping;
+                unset($fieldMappings[$name]);
+                continue;
+            }
+
+            $fieldMappings[$name] = $fieldMapping;
+        }
+
+        if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
+            $ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
+        }
+
+        if ($ids) {
+            $array['fields'] = $ids;
+        }
+
+        if ($fieldMappings) {
+            if ( ! isset($array['fields'])) {
+                $array['fields'] = array();
+            }
+            $array['fields'] = array_merge($array['fields'], $fieldMappings);
+        }
+
+        $associations = array();
+        foreach ($metadata->associationMappings as $name => $associationMapping) {
+            $cascade = array();
+            if ($associationMapping['isCascadeRemove']) {
+                $cascade[] = 'remove';
+            }
+            if ($associationMapping['isCascadePersist']) {
+                $cascade[] = 'persist';
+            }
+            if ($associationMapping['isCascadeRefresh']) {
+                $cascade[] = 'refresh';
+            }
+            if ($associationMapping['isCascadeMerge']) {
+                $cascade[] = 'merge';
+            }
+            if ($associationMapping['isCascadeDetach']) {
+                $cascade[] = 'detach';
+            }
+            if (count($cascade) === 5) {
+                $cascade = array('all');
+            }
+            $associationMappingArray = array(
+                'targetEntity' => $associationMapping['targetEntity'],
+                'cascade'     => $cascade,
+            );
+
+            if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
+                $joinColumns = $associationMapping['joinColumns'];
+                $newJoinColumns = array();
+                foreach ($joinColumns as $joinColumn) {
+                    $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
+                    if (isset($joinColumn['onDelete'])) {
+                        $newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete'];
+                    }
+                }
+                $oneToOneMappingArray = array(
+                    'mappedBy'      => $associationMapping['mappedBy'],
+                    'inversedBy'    => $associationMapping['inversedBy'],
+                    'joinColumns'   => $newJoinColumns,
+                    'orphanRemoval' => $associationMapping['orphanRemoval'],
+                );
+
+                $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
+
+                if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) {
+                    $array['oneToOne'][$name] = $associationMappingArray;
+                } else {
+                    $array['manyToOne'][$name] = $associationMappingArray;
+                }
+
+            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
+                $oneToManyMappingArray = array(
+                    'mappedBy'      => $associationMapping['mappedBy'],
+                    'inversedBy'    => $associationMapping['inversedBy'],
+                    'orphanRemoval' => $associationMapping['orphanRemoval'],
+                    'orderBy'       => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
+                );
+
+                $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
+                $array['oneToMany'][$name] = $associationMappingArray;
+            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
+                $manyToManyMappingArray = array(
+                    'mappedBy'   => $associationMapping['mappedBy'],
+                    'inversedBy' => $associationMapping['inversedBy'],
+                    'joinTable'  => isset($associationMapping['joinTable']) ? $associationMapping['joinTable'] : null,
+                    'orderBy'    => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
+                );
+
+                $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
+                $array['manyToMany'][$name] = $associationMappingArray;
+            }
+        }
+        if (isset($metadata->lifecycleCallbacks)) {
+            $array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks;
+        }
+
+        return \Symfony\Component\Yaml\Yaml::dump(array($metadata->name => $array), 10);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ExportException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ExportException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Export/ExportException.php	(revision 345)
@@ -0,0 +1,23 @@
+<?php
+
+namespace Doctrine\ORM\Tools\Export;
+
+use Doctrine\ORM\ORMException;
+
+class ExportException extends ORMException
+{
+    public static function invalidExporterDriverType($type)
+    {
+        return new self("The specified export driver '$type' does not exist");
+    }
+
+    public static function invalidMappingDriverType($type)
+    {
+        return new self("The mapping driver '$type' does not exist");
+    }
+
+    public static function attemptOverwriteExistingFile($file)
+    {
+        return new self("Attempting to overwrite an existing file '".$file."'.");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/CountWalker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/CountWalker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/CountWalker.php	(revision 345)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Doctrine ORM
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to kontakt@beberlei.de so I can send you a copy immediately.
+ */
+
+namespace Doctrine\ORM\Tools\Pagination;
+
+use Doctrine\ORM\Query\TreeWalkerAdapter,
+    Doctrine\ORM\Query\AST\SelectStatement,
+    Doctrine\ORM\Query\AST\SelectExpression,
+    Doctrine\ORM\Query\AST\PathExpression,
+    Doctrine\ORM\Query\AST\AggregateExpression;
+
+/**
+ * Replaces the selectClause of the AST with a COUNT statement
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+class CountWalker extends TreeWalkerAdapter
+{
+    /**
+     * Distinct mode hint name
+     */
+    const HINT_DISTINCT = 'doctrine_paginator.distinct';
+
+    /**
+     * Walks down a SelectStatement AST node, modifying it to retrieve a COUNT
+     *
+     * @param SelectStatement $AST
+     * @return void
+     */
+    public function walkSelectStatement(SelectStatement $AST)
+    {
+        $rootComponents = array();
+        foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
+            $isParent = array_key_exists('parent', $qComp)
+                && $qComp['parent'] === null
+                && $qComp['nestingLevel'] == 0
+            ;
+            if ($isParent) {
+                $rootComponents[] = array($dqlAlias => $qComp);
+            }
+        }
+        if (count($rootComponents) > 1) {
+            throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
+        }
+        $root = reset($rootComponents);
+        $parentName = key($root);
+        $parent = current($root);
+
+        $pathExpression = new PathExpression(
+            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
+            $parent['metadata']->getSingleIdentifierFieldName()
+        );
+        $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+
+        $distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
+        $AST->selectClause->selectExpressions = array(
+            new SelectExpression(
+                new AggregateExpression('count', $pathExpression, $distinct), null
+            )
+        );
+
+        // ORDER BY is not needed, only increases query execution through unnecessary sorting.
+        $AST->orderByClause = null;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php	(revision 345)
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Doctrine ORM
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE. This license can also be viewed
+ * at http://hobodave.com/license.txt
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+
+namespace Doctrine\ORM\Tools\Pagination;
+
+use Doctrine\DBAL\Types\Type,
+    Doctrine\ORM\Query\TreeWalkerAdapter,
+    Doctrine\ORM\Query\AST\SelectStatement,
+    Doctrine\ORM\Query\AST\SelectExpression,
+    Doctrine\ORM\Query\AST\PathExpression,
+    Doctrine\ORM\Query\AST\AggregateExpression;
+
+/**
+ * Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+class LimitSubqueryWalker extends TreeWalkerAdapter
+{
+    /**
+     * ID type hint
+     */
+    const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
+
+    /**
+     * @var int Counter for generating unique order column aliases
+     */
+    private $_aliasCounter = 0;
+
+    /**
+     * Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
+     * of the root Entity
+     *
+     * @param SelectStatement $AST
+     * @return void
+     */
+    public function walkSelectStatement(SelectStatement $AST)
+    {
+        $parent = null;
+        $parentName = null;
+        $selectExpressions = array();
+
+        foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
+            // preserve mixed data in query for ordering
+            if (isset($qComp['resultVariable'])) {
+                $selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias);
+                continue;
+            }
+
+            if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
+                $parent = $qComp;
+                $parentName = $dqlAlias;
+                continue;
+            }
+        }
+
+        $identifier = $parent['metadata']->getSingleIdentifierFieldName();
+        $this->_getQuery()->setHint(
+            self::IDENTIFIER_TYPE,
+            Type::getType($parent['metadata']->getTypeOfField($identifier))
+        );
+
+        $pathExpression = new PathExpression(
+            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
+            $parentName,
+            $identifier
+        );
+        $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+
+        array_unshift($selectExpressions, new SelectExpression($pathExpression, '_dctrn_id'));
+        $AST->selectClause->selectExpressions = $selectExpressions;
+
+        if (isset($AST->orderByClause)) {
+            foreach ($AST->orderByClause->orderByItems as $item) {
+                if ($item->expression instanceof PathExpression) {
+                    $pathExpression = new PathExpression(
+                        PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
+                        $item->expression->identificationVariable,
+                        $item->expression->field
+                    );
+                    $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+                    $AST->selectClause->selectExpressions[] = new SelectExpression(
+                        $pathExpression,
+                    	'_dctrn_ord' . $this->_aliasCounter++
+                    );
+                }
+            }
+        }
+
+        $AST->selectClause->isDistinct = true;
+    }
+
+}
+
+
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/Paginator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/Paginator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/Paginator.php	(revision 345)
@@ -0,0 +1,180 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools\Pagination;
+
+use Doctrine\ORM\QueryBuilder;
+use Doctrine\ORM\Query;
+use Doctrine\ORM\NoResultException;
+use Doctrine\ORM\Tools\Pagination\WhereInWalker;
+use Doctrine\ORM\Tools\Pagination\CountWalker;
+use Countable;
+use IteratorAggregate;
+use ArrayIterator;
+
+/**
+ * Paginator
+ *
+ * The paginator can handle various complex scenarios with DQL.
+ *
+ * @author Pablo DÃ­ez <pablodip@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @license New BSD
+ */
+class Paginator implements \Countable, \IteratorAggregate
+{
+    /**
+     * @var Query
+     */
+    private $query;
+
+    /**
+     * @var bool
+     */
+    private $fetchJoinCollection;
+
+    /**
+     * @var int
+     */
+    private $count;
+
+    /**
+     * Constructor.
+     *
+     * @param Query|QueryBuilder $query A Doctrine ORM query or query builder.
+     * @param Boolean $fetchJoinCollection Whether the query joins a collection (true by default).
+     */
+    public function __construct($query, $fetchJoinCollection = true)
+    {
+        if ($query instanceof QueryBuilder) {
+            $query = $query->getQuery();
+        }
+
+        $this->query = $query;
+        $this->fetchJoinCollection = (Boolean) $fetchJoinCollection;
+    }
+
+    /**
+     * Returns the query
+     *
+     * @return Query
+     */
+    public function getQuery()
+    {
+        return $this->query;
+    }
+
+    /**
+     * Returns whether the query joins a collection.
+     *
+     * @return Boolean Whether the query joins a collection.
+     */
+    public function getFetchJoinCollection()
+    {
+        return $this->fetchJoinCollection;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count()
+    {
+        if ($this->count === null) {
+            /* @var $countQuery Query */
+            $countQuery = $this->cloneQuery($this->query);
+
+            if ( ! $countQuery->getHint(CountWalker::HINT_DISTINCT)) {
+                $countQuery->setHint(CountWalker::HINT_DISTINCT, true);
+            }
+
+            $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker'));
+            $countQuery->setFirstResult(null)->setMaxResults(null);
+
+            try {
+                $data =  $countQuery->getScalarResult();
+                $data = array_map('current', $data);
+                $this->count = array_sum($data);
+            } catch(NoResultException $e) {
+                $this->count = 0;
+            }
+        }
+        return $this->count;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $offset = $this->query->getFirstResult();
+        $length = $this->query->getMaxResults();
+
+        if ($this->fetchJoinCollection) {
+            $subQuery = $this->cloneQuery($this->query);
+            $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'))
+                ->setFirstResult($offset)
+                ->setMaxResults($length);
+
+            $ids = array_map('current', $subQuery->getScalarResult());
+
+            $whereInQuery = $this->cloneQuery($this->query);
+            // don't do this for an empty id array
+            if (count($ids) > 0) {
+                $namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
+
+                $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
+                $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
+                $whereInQuery->setFirstResult(null)->setMaxResults(null);
+                foreach ($ids as $i => $id) {
+                    $i++;
+                    $whereInQuery->setParameter("{$namespace}_{$i}", $id);
+                }
+            }
+
+            $result = $whereInQuery->getResult($this->query->getHydrationMode());
+        } else {
+            $result = $this->cloneQuery($this->query)
+                ->setMaxResults($length)
+                ->setFirstResult($offset)
+                ->getResult($this->query->getHydrationMode())
+            ;
+        }
+        return new \ArrayIterator($result);
+    }
+
+    /**
+     * Clones a query.
+     *
+     * @param Query $query The query.
+     *
+     * @return Query The cloned query.
+     */
+    private function cloneQuery(Query $query)
+    {
+        /* @var $cloneQuery Query */
+        $cloneQuery = clone $query;
+        $cloneQuery->setParameters($query->getParameters());
+        foreach ($query->getHints() as $name => $value) {
+            $cloneQuery->setHint($name, $value);
+        }
+
+        return $cloneQuery;
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/WhereInWalker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/WhereInWalker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/WhereInWalker.php	(revision 345)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Doctrine ORM
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE. This license can also be viewed
+ * at http://hobodave.com/license.txt
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+
+namespace Doctrine\ORM\Tools\Pagination;
+
+use Doctrine\ORM\Query\AST\ArithmeticExpression,
+    Doctrine\ORM\Query\AST\SimpleArithmeticExpression,
+    Doctrine\ORM\Query\TreeWalkerAdapter,
+    Doctrine\ORM\Query\AST\SelectStatement,
+    Doctrine\ORM\Query\AST\PathExpression,
+    Doctrine\ORM\Query\AST\InExpression,
+    Doctrine\ORM\Query\AST\NullComparisonExpression,
+    Doctrine\ORM\Query\AST\InputParameter,
+    Doctrine\ORM\Query\AST\ConditionalPrimary,
+    Doctrine\ORM\Query\AST\ConditionalTerm,
+    Doctrine\ORM\Query\AST\ConditionalExpression,
+    Doctrine\ORM\Query\AST\ConditionalFactor,
+    Doctrine\ORM\Query\AST\WhereClause;
+
+/**
+ * Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+class WhereInWalker extends TreeWalkerAdapter
+{
+    /**
+     * ID Count hint name
+     */
+    const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
+
+    /**
+     * Primary key alias for query
+     */
+    const PAGINATOR_ID_ALIAS = 'dpid';
+
+    /**
+     * Replaces the whereClause in the AST
+     *
+     * Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
+     *
+     * The parameter namespace (dpid) is defined by
+     * the PAGINATOR_ID_ALIAS
+     *
+     * The total number of parameters is retrieved from
+     * the HINT_PAGINATOR_ID_COUNT query hint
+     *
+     * @param  SelectStatement $AST
+     * @return void
+     */
+    public function walkSelectStatement(SelectStatement $AST)
+    {
+        $rootComponents = array();
+        foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
+            $isParent = array_key_exists('parent', $qComp)
+                && $qComp['parent'] === null
+                && $qComp['nestingLevel'] == 0
+            ;
+            if ($isParent) {
+                $rootComponents[] = array($dqlAlias => $qComp);
+            }
+        }
+        if (count($rootComponents) > 1) {
+            throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
+        }
+        $root = reset($rootComponents);
+        $parentName = key($root);
+        $parent = current($root);
+
+        $pathExpression = new PathExpression(
+            PathExpression::TYPE_STATE_FIELD, $parentName, $parent['metadata']->getSingleIdentifierFieldName()
+        );
+        $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+
+        $count = $this->_getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT);
+
+        if ($count > 0) {
+            $arithmeticExpression = new ArithmeticExpression();
+            $arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression(
+                array($pathExpression)
+            );
+            $expression = new InExpression($arithmeticExpression);
+            $ns = self::PAGINATOR_ID_ALIAS;
+
+            for ($i = 1; $i <= $count; $i++) {
+                $expression->literals[] = new InputParameter(":{$ns}_$i");
+            }
+        } else {
+            $expression = new NullComparisonExpression($pathExpression);
+            $expression->not = false;
+        }
+
+        $conditionalPrimary = new ConditionalPrimary;
+        $conditionalPrimary->simpleConditionalExpression = $expression;
+        if ($AST->whereClause) {
+            if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) {
+                $AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary;
+            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) {
+                $AST->whereClause->conditionalExpression = new ConditionalExpression(array(
+                    new ConditionalTerm(array(
+                        $AST->whereClause->conditionalExpression,
+                        $conditionalPrimary
+                    ))
+                ));
+            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression) {
+                $tmpPrimary = new ConditionalPrimary;
+                $tmpPrimary->conditionalExpression = $AST->whereClause->conditionalExpression;
+                $AST->whereClause->conditionalExpression = new ConditionalTerm(array(
+                    $tmpPrimary,
+                    $conditionalPrimary
+                ));
+            }
+        } else {
+            $AST->whereClause = new WhereClause(
+                new ConditionalExpression(array(
+                    new ConditionalTerm(array(
+                        $conditionalPrimary
+                    ))
+                ))
+            );
+        }
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ResolveTargetEntityListener.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ResolveTargetEntityListener.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ResolveTargetEntityListener.php	(revision 345)
@@ -0,0 +1,94 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
+use Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * ResolveTargetEntityListener
+ *
+ * Mechanism to overwrite interfaces or classes specified as association
+ * targets.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.2
+ */
+class ResolveTargetEntityListener
+{
+    /**
+     * @var array
+     */
+    private $resolveTargetEntities = array();
+
+    /**
+     * Add a target-entity class name to resolve to a new class name.
+     *
+     * @param string $originalEntity
+     * @param string $newEntity
+     * @param array $mapping
+     * @return void
+     */
+    public function addResolveTargetEntity($originalEntity, $newEntity, array $mapping)
+    {
+        $mapping['targetEntity'] = ltrim($newEntity, "\\");
+        $this->resolveTargetEntities[ltrim($originalEntity, "\\")] = $mapping;
+    }
+
+    /**
+     * Process event and resolve new target entity names.
+     *
+     * @param LoadClassMetadataEventArgs $args
+     * @return void
+     */
+    public function loadClassMetadata(LoadClassMetadataEventArgs $args)
+    {
+        $cm = $args->getClassMetadata();
+        foreach ($cm->associationMappings as $assocName => $mapping) {
+            if (isset($this->resolveTargetEntities[$mapping['targetEntity']])) {
+                $this->remapAssociation($cm, $mapping);
+            }
+        }
+    }
+
+    private function remapAssociation($classMetadata, $mapping)
+    {
+        $newMapping = $this->resolveTargetEntities[$mapping['targetEntity']];
+        $newMapping = array_replace_recursive($mapping, $newMapping);
+        $newMapping['fieldName'] = $mapping['fieldName'];
+        unset($classMetadata->associationMappings[$mapping['fieldName']]);
+
+        switch ($mapping['type']) {
+            case ClassMetadata::MANY_TO_MANY:
+                $classMetadata->mapManyToMany($newMapping);
+                break;
+            case ClassMetadata::MANY_TO_ONE:
+                $classMetadata->mapManyToOne($newMapping);
+                break;
+            case ClassMetadata::ONE_TO_MANY:
+                $classMetadata->mapOneToMany($newMapping);
+                break;
+            case ClassMetadata::ONE_TO_ONE:
+                $classMetadata->mapOneToOne($newMapping);
+                break;
+        }
+    }
+}
+
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaTool.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaTool.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaTool.php	(revision 345)
@@ -0,0 +1,701 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\ORMException,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Schema\Schema,
+    Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets,
+    Doctrine\ORM\EntityManager,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Internal\CommitOrderCalculator,
+    Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs,
+    Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
+
+/**
+ * The SchemaTool is a tool to create/drop/update database schemas based on
+ * <tt>ClassMetadata</tt> class descriptors.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class SchemaTool
+{
+    /**
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $_em;
+
+    /**
+     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    private $_platform;
+
+    /**
+     * Initializes a new SchemaTool instance that uses the connection of the
+     * provided EntityManager.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->_em = $em;
+        $this->_platform = $em->getConnection()->getDatabasePlatform();
+    }
+
+    /**
+     * Creates the database schema for the given array of ClassMetadata instances.
+     *
+     * @throws ToolsException
+     * @param array $classes
+     * @return void
+     */
+    public function createSchema(array $classes)
+    {
+        $createSchemaSql = $this->getCreateSchemaSql($classes);
+        $conn = $this->_em->getConnection();
+
+        foreach ($createSchemaSql as $sql) {
+            try {
+                $conn->executeQuery($sql);
+            } catch(\Exception $e) {
+                throw ToolsException::schemaToolFailure($sql, $e);
+            }
+        }
+    }
+
+    /**
+     * Gets the list of DDL statements that are required to create the database schema for
+     * the given list of ClassMetadata instances.
+     *
+     * @param array $classes
+     * @return array $sql The SQL statements needed to create the schema for the classes.
+     */
+    public function getCreateSchemaSql(array $classes)
+    {
+        $schema = $this->getSchemaFromMetadata($classes);
+        return $schema->toSql($this->_platform);
+    }
+
+    /**
+     * Some instances of ClassMetadata don't need to be processed in the SchemaTool context. This method detects them.
+     *
+     * @param ClassMetadata $class
+     * @param array $processedClasses
+     * @return bool
+     */
+    private function processingNotRequired($class, array $processedClasses)
+    {
+        return (
+            isset($processedClasses[$class->name]) ||
+            $class->isMappedSuperclass ||
+            ($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
+        );
+    }
+
+    /**
+     * From a given set of metadata classes this method creates a Schema instance.
+     *
+     * @param array $classes
+     * @return Schema
+     */
+    public function getSchemaFromMetadata(array $classes)
+    {
+        $processedClasses = array(); // Reminder for processed classes, used for hierarchies
+
+        $sm = $this->_em->getConnection()->getSchemaManager();
+        $metadataSchemaConfig = $sm->createSchemaConfig();
+        $metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
+        $schema = new Schema(array(), array(), $metadataSchemaConfig);
+
+        $evm = $this->_em->getEventManager();
+
+        foreach ($classes as $class) {
+            if ($this->processingNotRequired($class, $processedClasses)) {
+                continue;
+            }
+
+            $table = $schema->createTable($class->getQuotedTableName($this->_platform));
+
+            $columns = array(); // table columns
+
+            if ($class->isInheritanceTypeSingleTable()) {
+                $columns = $this->_gatherColumns($class, $table);
+                $this->_gatherRelationsSql($class, $table, $schema);
+
+                // Add the discriminator column
+                $this->addDiscriminatorColumnDefinition($class, $table);
+
+                // Aggregate all the information from all classes in the hierarchy
+                foreach ($class->parentClasses as $parentClassName) {
+                    // Parent class information is already contained in this class
+                    $processedClasses[$parentClassName] = true;
+                }
+
+                foreach ($class->subClasses as $subClassName) {
+                    $subClass = $this->_em->getClassMetadata($subClassName);
+                    $this->_gatherColumns($subClass, $table);
+                    $this->_gatherRelationsSql($subClass, $table, $schema);
+                    $processedClasses[$subClassName] = true;
+                }
+            } else if ($class->isInheritanceTypeJoined()) {
+                // Add all non-inherited fields as columns
+                $pkColumns = array();
+                foreach ($class->fieldMappings as $fieldName => $mapping) {
+                    if ( ! isset($mapping['inherited'])) {
+                        $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
+                        $this->_gatherColumn($class, $mapping, $table);
+
+                        if ($class->isIdentifier($fieldName)) {
+                            $pkColumns[] = $columnName;
+                        }
+                    }
+                }
+
+                $this->_gatherRelationsSql($class, $table, $schema);
+
+                // Add the discriminator column only to the root table
+                if ($class->name == $class->rootEntityName) {
+                    $this->addDiscriminatorColumnDefinition($class, $table);
+                } else {
+                    // Add an ID FK column to child tables
+                    /* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
+                    $idMapping = $class->fieldMappings[$class->identifier[0]];
+                    $this->_gatherColumn($class, $idMapping, $table);
+                    $columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
+                    // TODO: This seems rather hackish, can we optimize it?
+                    $table->getColumn($columnName)->setAutoincrement(false);
+
+                    $pkColumns[] = $columnName;
+
+                    // Add a FK constraint on the ID column
+                    $table->addUnnamedForeignKeyConstraint(
+                        $this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
+                        array($columnName), array($columnName), array('onDelete' => 'CASCADE')
+                    );
+                }
+
+                $table->setPrimaryKey($pkColumns);
+
+            } else if ($class->isInheritanceTypeTablePerClass()) {
+                throw ORMException::notSupported();
+            } else {
+                $this->_gatherColumns($class, $table);
+                $this->_gatherRelationsSql($class, $table, $schema);
+            }
+
+            $pkColumns = array();
+            foreach ($class->identifier AS $identifierField) {
+                if (isset($class->fieldMappings[$identifierField])) {
+                    $pkColumns[] = $class->getQuotedColumnName($identifierField, $this->_platform);
+                } else if (isset($class->associationMappings[$identifierField])) {
+                    /* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
+                    $assoc = $class->associationMappings[$identifierField];
+                    foreach ($assoc['joinColumns'] AS $joinColumn) {
+                        $pkColumns[] = $joinColumn['name'];
+                    }
+                }
+            }
+            if (!$table->hasIndex('primary')) {
+                $table->setPrimaryKey($pkColumns);
+            }
+
+            if (isset($class->table['indexes'])) {
+                foreach ($class->table['indexes'] AS $indexName => $indexData) {
+                    $table->addIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName);
+                }
+            }
+
+            if (isset($class->table['uniqueConstraints'])) {
+                foreach ($class->table['uniqueConstraints'] AS $indexName => $indexData) {
+                    $table->addUniqueIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName);
+                }
+            }
+
+            $processedClasses[$class->name] = true;
+
+            if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
+                $seqDef = $class->sequenceGeneratorDefinition;
+
+                if (!$schema->hasSequence($seqDef['sequenceName'])) {
+                    $schema->createSequence(
+                        $seqDef['sequenceName'],
+                        $seqDef['allocationSize'],
+                        $seqDef['initialValue']
+                    );
+                }
+            }
+
+            if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) {
+                $evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
+            }
+        }
+
+        if ( ! $this->_platform->supportsSchemas() && ! $this->_platform->canEmulateSchemas() ) {
+            $schema->visit(new RemoveNamespacedAssets());
+        }
+
+        if ($evm->hasListeners(ToolEvents::postGenerateSchema)) {
+            $evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema));
+        }
+
+        return $schema;
+    }
+
+    /**
+     * Gets a portable column definition as required by the DBAL for the discriminator
+     * column of a class.
+     *
+     * @param ClassMetadata $class
+     * @return array The portable column definition of the discriminator column as required by
+     *              the DBAL.
+     */
+    private function addDiscriminatorColumnDefinition($class, $table)
+    {
+        $discrColumn = $class->discriminatorColumn;
+
+        if (!isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) {
+            $discrColumn['type'] = 'string';
+            $discrColumn['length'] = 255;
+        }
+
+        $table->addColumn(
+            $discrColumn['name'],
+            $discrColumn['type'],
+            array('length' => $discrColumn['length'], 'notnull' => true)
+        );
+    }
+
+    /**
+     * Gathers the column definitions as required by the DBAL of all field mappings
+     * found in the given class.
+     *
+     * @param ClassMetadata $class
+     * @param Table $table
+     * @return array The list of portable column definitions as required by the DBAL.
+     */
+    private function _gatherColumns($class, $table)
+    {
+        $columns = array();
+        $pkColumns = array();
+
+        foreach ($class->fieldMappings as $fieldName => $mapping) {
+            if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
+                continue;
+            }
+
+            $column = $this->_gatherColumn($class, $mapping, $table);
+
+            if ($class->isIdentifier($mapping['fieldName'])) {
+                $pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
+            }
+        }
+
+        // For now, this is a hack required for single table inheritence, since this method is called
+        // twice by single table inheritence relations
+        if(!$table->hasIndex('primary')) {
+            //$table->setPrimaryKey($pkColumns);
+        }
+
+        return $columns;
+    }
+
+    /**
+     * Creates a column definition as required by the DBAL from an ORM field mapping definition.
+     *
+     * @param ClassMetadata $class The class that owns the field mapping.
+     * @param array $mapping The field mapping.
+     * @param Table $table
+     * @return array The portable column definition as required by the DBAL.
+     */
+    private function _gatherColumn($class, array $mapping, $table)
+    {
+        $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
+        $columnType = $mapping['type'];
+
+        $options = array();
+        $options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
+        $options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
+        if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
+            $options['notnull'] = false;
+        }
+
+        $options['platformOptions'] = array();
+        $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
+
+        if(strtolower($columnType) == 'string' && $options['length'] === null) {
+            $options['length'] = 255;
+        }
+
+        if (isset($mapping['precision'])) {
+            $options['precision'] = $mapping['precision'];
+        }
+
+        if (isset($mapping['scale'])) {
+            $options['scale'] = $mapping['scale'];
+        }
+
+        if (isset($mapping['default'])) {
+            $options['default'] = $mapping['default'];
+        }
+
+        if (isset($mapping['columnDefinition'])) {
+            $options['columnDefinition'] = $mapping['columnDefinition'];
+        }
+
+        if (isset($mapping['options'])) {
+            $options['customSchemaOptions'] = $mapping['options'];
+        }
+
+        if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
+            $options['autoincrement'] = true;
+        }
+        if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) {
+            $options['autoincrement'] = false;
+        }
+
+        if ($table->hasColumn($columnName)) {
+            // required in some inheritance scenarios
+            $table->changeColumn($columnName, $options);
+        } else {
+            $table->addColumn($columnName, $columnType, $options);
+        }
+
+        $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false;
+        if ($isUnique) {
+            $table->addUniqueIndex(array($columnName));
+        }
+    }
+
+    /**
+     * Gathers the SQL for properly setting up the relations of the given class.
+     * This includes the SQL for foreign key constraints and join tables.
+     *
+     * @param ClassMetadata $class
+     * @param \Doctrine\DBAL\Schema\Table $table
+     * @param \Doctrine\DBAL\Schema\Schema $schema
+     * @return void
+     */
+    private function _gatherRelationsSql($class, $table, $schema)
+    {
+        foreach ($class->associationMappings as $fieldName => $mapping) {
+            if (isset($mapping['inherited'])) {
+                continue;
+            }
+
+            $foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']);
+
+            if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
+                $primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type
+
+                $this->_gatherRelationJoinColumns($mapping['joinColumns'], $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
+
+                foreach($uniqueConstraints AS $indexName => $unique) {
+                    $table->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
+                }
+            } else if ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
+                //... create join table, one-many through join table supported later
+                throw ORMException::notSupported();
+            } else if ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
+                // create join table
+                $joinTable = $mapping['joinTable'];
+
+                $theJoinTable = $schema->createTable($foreignClass->getQuotedJoinTableName($mapping, $this->_platform));
+
+                $primaryKeyColumns = $uniqueConstraints = array();
+
+                // Build first FK constraint (relation table => source table)
+                $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints);
+
+                // Build second FK constraint (relation table => target table)
+                $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
+
+                $theJoinTable->setPrimaryKey($primaryKeyColumns);
+
+                foreach($uniqueConstraints AS $indexName => $unique) {
+                    $theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the class metadata that is responsible for the definition of the referenced column name.
+     *
+     * Previously this was a simple task, but with DDC-117 this problem is actually recursive. If its
+     * not a simple field, go through all identifier field names that are associations recursivly and
+     * find that referenced column name.
+     *
+     * TODO: Is there any way to make this code more pleasing?
+     *
+     * @param ClassMetadata $class
+     * @param string $referencedColumnName
+     * @return array(ClassMetadata, referencedFieldName)
+     */
+    private function getDefiningClass($class, $referencedColumnName)
+    {
+        $referencedFieldName = $class->getFieldName($referencedColumnName);
+
+        if ($class->hasField($referencedFieldName)) {
+            return array($class, $referencedFieldName);
+        } else if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
+            // it seems to be an entity as foreign key
+            foreach ($class->getIdentifierFieldNames() AS $fieldName) {
+                if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
+                    return $this->getDefiningClass(
+                        $this->_em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
+                        $class->getSingleAssociationReferencedJoinColumnName($fieldName)
+                    );
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gather columns and fk constraints that are required for one part of relationship.
+     *
+     * @param array $joinColumns
+     * @param \Doctrine\DBAL\Schema\Table $theJoinTable
+     * @param ClassMetadata $class
+     * @param array $mapping
+     * @param array $primaryKeyColumns
+     * @param array $uniqueConstraints
+     */
+    private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints)
+    {
+        $localColumns = array();
+        $foreignColumns = array();
+        $fkOptions = array();
+        $foreignTableName = $class->getQuotedTableName($this->_platform);
+
+        foreach ($joinColumns as $joinColumn) {
+            $columnName = $joinColumn['name'];
+            list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']);
+
+            if (!$definingClass) {
+                throw new \Doctrine\ORM\ORMException(
+                    "Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ".
+                    $mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist."
+                );
+            }
+
+            $primaryKeyColumns[] = $columnName;
+            $localColumns[] = $columnName;
+            $foreignColumns[] = $joinColumn['referencedColumnName'];
+
+            if ( ! $theJoinTable->hasColumn($joinColumn['name'])) {
+                // Only add the column to the table if it does not exist already.
+                // It might exist already if the foreign key is mapped into a regular
+                // property as well.
+
+                $fieldMapping = $definingClass->getFieldMapping($referencedFieldName);
+
+                $columnDef = null;
+                if (isset($joinColumn['columnDefinition'])) {
+                    $columnDef = $joinColumn['columnDefinition'];
+                } else if (isset($fieldMapping['columnDefinition'])) {
+                    $columnDef = $fieldMapping['columnDefinition'];
+                }
+                $columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef);
+                if (isset($joinColumn['nullable'])) {
+                    $columnOptions['notnull'] = !$joinColumn['nullable'];
+                }
+                if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
+                    $columnOptions['length'] = $fieldMapping['length'];
+                } else if ($fieldMapping['type'] == "decimal") {
+                    $columnOptions['scale'] = $fieldMapping['scale'];
+                    $columnOptions['precision'] = $fieldMapping['precision'];
+                }
+
+                $theJoinTable->addColumn($columnName, $fieldMapping['type'], $columnOptions);
+            }
+
+            if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
+                $uniqueConstraints[] = array('columns' => array($columnName));
+            }
+
+            if (isset($joinColumn['onDelete'])) {
+                $fkOptions['onDelete'] = $joinColumn['onDelete'];
+            }
+        }
+
+        $theJoinTable->addUnnamedForeignKeyConstraint(
+            $foreignTableName, $localColumns, $foreignColumns, $fkOptions
+        );
+    }
+
+    /**
+     * Drops the database schema for the given classes.
+     *
+     * In any way when an exception is thrown it is supressed since drop was
+     * issued for all classes of the schema and some probably just don't exist.
+     *
+     * @param array $classes
+     * @return void
+     */
+    public function dropSchema(array $classes)
+    {
+        $dropSchemaSql = $this->getDropSchemaSQL($classes);
+        $conn = $this->_em->getConnection();
+
+        foreach ($dropSchemaSql as $sql) {
+            try {
+                $conn->executeQuery($sql);
+            } catch(\Exception $e) {
+
+            }
+        }
+    }
+
+    /**
+     * Drops all elements in the database of the current connection.
+     *
+     * @return void
+     */
+    public function dropDatabase()
+    {
+        $dropSchemaSql = $this->getDropDatabaseSQL();
+        $conn = $this->_em->getConnection();
+
+        foreach ($dropSchemaSql as $sql) {
+            $conn->executeQuery($sql);
+        }
+    }
+
+    /**
+     * Gets the SQL needed to drop the database schema for the connections database.
+     *
+     * @return array
+     */
+    public function getDropDatabaseSQL()
+    {
+        $sm = $this->_em->getConnection()->getSchemaManager();
+        $schema = $sm->createSchema();
+
+        $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
+        /* @var $schema \Doctrine\DBAL\Schema\Schema */
+        $schema->visit($visitor);
+        return $visitor->getQueries();
+    }
+
+    /**
+     * Get SQL to drop the tables defined by the passed classes.
+     *
+     * @param array $classes
+     * @return array
+     */
+    public function getDropSchemaSQL(array $classes)
+    {
+        $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
+        $schema = $this->getSchemaFromMetadata($classes);
+
+        $sm = $this->_em->getConnection()->getSchemaManager();
+        $fullSchema = $sm->createSchema();
+        foreach ($fullSchema->getTables() AS $table) {
+            if (!$schema->hasTable($table->getName())) {
+                foreach ($table->getForeignKeys() AS $foreignKey) {
+                    /* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */
+                    if ($schema->hasTable($foreignKey->getForeignTableName())) {
+                        $visitor->acceptForeignKey($table, $foreignKey);
+                    }
+                }
+            } else {
+                $visitor->acceptTable($table);
+                foreach ($table->getForeignKeys() AS $foreignKey) {
+                    $visitor->acceptForeignKey($table, $foreignKey);
+                }
+            }
+        }
+
+        if ($this->_platform->supportsSequences()) {
+            foreach ($schema->getSequences() AS $sequence) {
+                $visitor->acceptSequence($sequence);
+            }
+            foreach ($schema->getTables() AS $table) {
+                /* @var $sequence Table */
+                if ($table->hasPrimaryKey()) {
+                    $columns = $table->getPrimaryKey()->getColumns();
+                    if (count($columns) == 1) {
+                        $checkSequence = $table->getName() . "_" . $columns[0] . "_seq";
+                        if ($fullSchema->hasSequence($checkSequence)) {
+                            $visitor->acceptSequence($fullSchema->getSequence($checkSequence));
+                        }
+                    }
+                }
+            }
+        }
+
+        return $visitor->getQueries();
+    }
+
+    /**
+     * Updates the database schema of the given classes by comparing the ClassMetadata
+     * instances to the current database schema that is inspected. If $saveMode is set
+     * to true the command is executed in the Database, else SQL is returned.
+     *
+     * @param array $classes
+     * @param boolean $saveMode
+     * @return void
+     */
+    public function updateSchema(array $classes, $saveMode=false)
+    {
+        $updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
+        $conn = $this->_em->getConnection();
+
+        foreach ($updateSchemaSql as $sql) {
+            $conn->executeQuery($sql);
+        }
+    }
+
+    /**
+     * Gets the sequence of SQL statements that need to be performed in order
+     * to bring the given class mappings in-synch with the relational schema.
+     * If $saveMode is set to true the command is executed in the Database,
+     * else SQL is returned.
+     *
+     * @param array $classes The classes to consider.
+     * @param boolean $saveMode True for writing to DB, false for SQL string
+     * @return array The sequence of SQL statements.
+     */
+    public function getUpdateSchemaSql(array $classes, $saveMode=false)
+    {
+        $sm = $this->_em->getConnection()->getSchemaManager();
+
+        $fromSchema = $sm->createSchema();
+        $toSchema = $this->getSchemaFromMetadata($classes);
+
+        $comparator = new \Doctrine\DBAL\Schema\Comparator();
+        $schemaDiff = $comparator->compare($fromSchema, $toSchema);
+
+        if ($saveMode) {
+            return $schemaDiff->toSaveSql($this->_platform);
+        } else {
+            return $schemaDiff->toSql($this->_platform);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaValidator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaValidator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/SchemaValidator.php	(revision 345)
@@ -0,0 +1,267 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Performs strict validation of the mapping schema
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class SchemaValidator
+{
+    /**
+     * @var EntityManager
+     */
+    private $em;
+
+    /**
+     * @param EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Checks the internal consistency of all mapping files.
+     *
+     * There are several checks that can't be done at runtime or are too expensive, which can be verified
+     * with this command. For example:
+     *
+     * 1. Check if a relation with "mappedBy" is actually connected to that specified field.
+     * 2. Check if "mappedBy" and "inversedBy" are consistent to each other.
+     * 3. Check if "referencedColumnName" attributes are really pointing to primary key columns.
+     * 4. Check if there are public properties that might cause problems with lazy loading.
+     *
+     * @return array
+     */
+    public function validateMapping()
+    {
+        $errors = array();
+        $cmf = $this->em->getMetadataFactory();
+        $classes = $cmf->getAllMetadata();
+
+        foreach ($classes AS $class) {
+            if ($ce = $this->validateClass($class)) {
+                $errors[$class->name] = $ce;
+            }
+        }
+
+        return $errors;
+    }
+
+    /**
+     * Validate a single class of the current
+     *
+     * @param ClassMetadataInfo $class
+     * @return array
+     */
+    public function validateClass(ClassMetadataInfo $class)
+    {
+        $ce = array();
+        $cmf = $this->em->getMetadataFactory();
+
+        foreach ($class->fieldMappings as $fieldName => $mapping) {
+            if (!Type::hasType($mapping['type'])) {
+                $ce[] = "The field '" . $class->name . "#" . $fieldName."' uses a non-existant type '" . $mapping['type'] . "'.";
+            }
+        }
+
+        foreach ($class->associationMappings AS $fieldName => $assoc) {
+            if (!class_exists($assoc['targetEntity']) || $cmf->isTransient($assoc['targetEntity'])) {
+                $ce[] = "The target entity '" . $assoc['targetEntity'] . "' specified on " . $class->name . '#' . $fieldName . ' is unknown or not an entity.';
+                return $ce;
+            }
+
+            if ($assoc['mappedBy'] && $assoc['inversedBy']) {
+                $ce[] = "The association " . $class . "#" . $fieldName . " cannot be defined as both inverse and owning.";
+            }
+
+            $targetMetadata = $cmf->getMetadataFor($assoc['targetEntity']);
+
+            if (isset($assoc['id']) && $targetMetadata->containsForeignIdentifier) {
+                $ce[] = "Cannot map association '" . $class->name. "#". $fieldName ." as identifier, because " .
+                        "the target entity '". $targetMetadata->name . "' also maps an association as identifier.";
+            }
+
+            /* @var $assoc AssociationMapping */
+            if ($assoc['mappedBy']) {
+                if ($targetMetadata->hasField($assoc['mappedBy'])) {
+                    $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
+                            "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which is not defined as association.";
+                }
+                if (!$targetMetadata->hasAssociation($assoc['mappedBy'])) {
+                    $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
+                            "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which does not exist.";
+                } else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] == null) {
+                    $ce[] = "The field " . $class->name . "#" . $fieldName . " is on the inverse side of a ".
+                            "bi-directional relationship, but the specified mappedBy association on the target-entity ".
+                            $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
+                            "'inversedBy=".$fieldName."' attribute.";
+                } else  if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) {
+                    $ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
+                            $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " are ".
+                            "incosistent with each other.";
+                }
+            }
+
+            if ($assoc['inversedBy']) {
+                if ($targetMetadata->hasField($assoc['inversedBy'])) {
+                    $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
+                            "field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which is not defined as association.";
+                }
+                if (!$targetMetadata->hasAssociation($assoc['inversedBy'])) {
+                    $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
+                            "field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which does not exist.";
+                } else if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] == null) {
+                    $ce[] = "The field " . $class->name . "#" . $fieldName . " is on the owning side of a ".
+                            "bi-directional relationship, but the specified mappedBy association on the target-entity ".
+                            $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
+                            "'inversedBy' attribute.";
+                } else  if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] != $fieldName) {
+                    $ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
+                            $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " are ".
+                            "incosistent with each other.";
+                }
+
+                // Verify inverse side/owning side match each other
+                if (array_key_exists($assoc['inversedBy'], $targetMetadata->associationMappings)) {
+                    $targetAssoc = $targetMetadata->associationMappings[$assoc['inversedBy']];
+                    if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){
+                        $ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " .
+                                "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well.";
+                    } else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
+                        $ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " .
+                                "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many.";
+                    } else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
+                        $ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " .
+                                "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well.";
+                    }
+                }
+            }
+
+            if ($assoc['isOwningSide']) {
+                if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY) {
+                    $identifierColumns = $class->getIdentifierColumnNames();
+                    foreach ($assoc['joinTable']['joinColumns'] AS $joinColumn) {
+                        if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
+                            $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
+                                "has to be a primary key column on the target entity class '".$class->name."'.";
+                            break;
+                        }
+                    }
+
+                    $identifierColumns = $targetMetadata->getIdentifierColumnNames();
+                    foreach ($assoc['joinTable']['inverseJoinColumns'] AS $inverseJoinColumn) {
+                        if (!in_array($inverseJoinColumn['referencedColumnName'], $identifierColumns)) {
+                            $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
+                                "has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
+                            break;
+                        }
+                    }
+
+                    if (count($targetMetadata->getIdentifierColumnNames()) != count($assoc['joinTable']['inverseJoinColumns'])) {
+                        $ce[] = "The inverse join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " .
+                                "have to contain to ALL identifier columns of the target entity '". $targetMetadata->name . "', " .
+                                "however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), array_values($assoc['relationToTargetKeyColumns']))) .
+                                "' are missing.";
+                    }
+
+                    if (count($class->getIdentifierColumnNames()) != count($assoc['joinTable']['joinColumns'])) {
+                        $ce[] = "The join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " .
+                                "have to contain to ALL identifier columns of the source entity '". $class->name . "', " .
+                                "however '" . implode(", ", array_diff($class->getIdentifierColumnNames(), array_values($assoc['relationToSourceKeyColumns']))) .
+                                "' are missing.";
+                    }
+
+                } else if ($assoc['type'] & ClassMetadataInfo::TO_ONE) {
+                    $identifierColumns = $targetMetadata->getIdentifierColumnNames();
+                    foreach ($assoc['joinColumns'] AS $joinColumn) {
+                        if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
+                            $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
+                                    "has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
+                        }
+                    }
+
+                    if (count($identifierColumns) != count($assoc['joinColumns'])) {
+                        $ids = array();
+                        foreach ($assoc['joinColumns'] AS $joinColumn) {
+                            $ids[] = $joinColumn['name'];
+                        }
+
+                        $ce[] = "The join columns of the association '" . $assoc['fieldName'] . "' " .
+                                "have to match to ALL identifier columns of the target entity '". $class->name . "', " .
+                                "however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), $ids)) .
+                                "' are missing.";
+                    }
+                }
+            }
+
+            if (isset($assoc['orderBy']) && $assoc['orderBy'] !== null) {
+                foreach ($assoc['orderBy'] AS $orderField => $orientation) {
+                    if (!$targetMetadata->hasField($orderField)) {
+                        $ce[] = "The association " . $class->name."#".$fieldName." is ordered by a foreign field " .
+                                $orderField . " that is not a field on the target entity " . $targetMetadata->name;
+                    }
+                }
+            }
+        }
+
+        foreach ($class->reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $publicAttr) {
+            if ($publicAttr->isStatic()) {
+                continue;
+            }
+            $ce[] = "Field '".$publicAttr->getName()."' in class '".$class->name."' must be private ".
+                    "or protected. Public fields may break lazy-loading.";
+        }
+
+        foreach ($class->subClasses AS $subClass) {
+            if (!in_array($class->name, class_parents($subClass))) {
+                $ce[] = "According to the discriminator map class '" . $subClass . "' has to be a child ".
+                        "of '" . $class->name . "' but these entities are not related through inheritance.";
+            }
+        }
+
+        return $ce;
+    }
+
+    /**
+     * Check if the Database Schema is in sync with the current metadata state.
+     *
+     * @return bool
+     */
+    public function schemaInSyncWithMetadata()
+    {
+        $schemaTool = new SchemaTool($this->em);
+
+        $allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
+        return (count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Setup.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Setup.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Setup.php	(revision 345)
@@ -0,0 +1,194 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\Common\ClassLoader;
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\ArrayCache;
+use Doctrine\ORM\Configuration;
+use Doctrine\ORM\Mapping\Driver\XmlDriver;
+use Doctrine\ORM\Mapping\Driver\YamlDriver;
+
+/**
+ * Convenience class for setting up Doctrine from different installations and configurations.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Setup
+{
+    /**
+     * Use this method to register all autoloaders for a setup where Doctrine is checked out from
+     * its github repository at {@link http://github.com/doctrine/doctrine2}
+     *
+     * @param string $gitCheckoutRootPath
+     * @return void
+     */
+    static public function registerAutoloadGit($gitCheckoutRootPath)
+    {
+        if (!class_exists('Doctrine\Common\ClassLoader', false)) {
+            require_once $gitCheckoutRootPath . "/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php";
+        }
+
+        $loader = new ClassLoader("Doctrine\Common", $gitCheckoutRootPath . "/lib/vendor/doctrine-common/lib");
+        $loader->register();
+
+        $loader = new ClassLoader("Doctrine\DBAL", $gitCheckoutRootPath . "/lib/vendor/doctrine-dbal/lib");
+        $loader->register();
+
+        $loader = new ClassLoader("Doctrine\ORM", $gitCheckoutRootPath . "/lib");
+        $loader->register();
+
+        $loader = new ClassLoader("Symfony\Component", $gitCheckoutRootPath . "/lib/vendor");
+        $loader->register();
+    }
+
+    /**
+     * Use this method to register all autoloaders for a setup where Doctrine is installed
+     * though {@link http://pear.doctrine-project.org}.
+     *
+     * @return void
+     */
+    static public function registerAutoloadPEAR()
+    {
+        if (!class_exists('Doctrine\Common\ClassLoader', false)) {
+            require_once "Doctrine/Common/ClassLoader.php";
+        }
+
+        $loader = new ClassLoader("Doctrine");
+        $loader->register();
+
+        $parts = explode(PATH_SEPARATOR, get_include_path());
+
+        foreach ($parts AS $includePath) {
+            if ($includePath != "." && file_exists($includePath . "/Doctrine")) {
+                $loader = new ClassLoader("Symfony\Component", $includePath . "/Doctrine");
+                $loader->register();
+                return;
+            }
+        }
+    }
+
+    /**
+     * Use this method to register all autoloads for a downloaded Doctrine library.
+     * Pick the directory the library was uncompressed into.
+     *
+     * @param string $directory
+     */
+    static public function registerAutoloadDirectory($directory)
+    {
+        if (!class_exists('Doctrine\Common\ClassLoader', false)) {
+            require_once $directory . "/Doctrine/Common/ClassLoader.php";
+        }
+
+        $loader = new ClassLoader("Doctrine", $directory);
+        $loader->register();
+
+        $loader = new ClassLoader("Symfony\Component", $directory . "/Doctrine");
+        $loader->register();
+    }
+
+    /**
+     * Create a configuration with an annotation metadata driver.
+     *
+     * @param array $paths
+     * @param boolean $isDevMode
+     * @param string $proxyDir
+     * @param Cache $cache
+     * @return Configuration
+     */
+    static public function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
+    {
+        $config = self::createConfiguration($isDevMode, $proxyDir, $cache);
+        $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths));
+        return $config;
+    }
+
+    /**
+     * Create a configuration with a xml metadata driver.
+     *
+     * @param array $paths
+     * @param boolean $isDevMode
+     * @param string $proxyDir
+     * @param Cache $cache
+     * @return Configuration
+     */
+    static public function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
+    {
+        $config = self::createConfiguration($isDevMode, $proxyDir, $cache);
+        $config->setMetadataDriverImpl(new XmlDriver($paths));
+        return $config;
+    }
+
+    /**
+     * Create a configuration with a yaml metadata driver.
+     *
+     * @param array $paths
+     * @param boolean $isDevMode
+     * @param string $proxyDir
+     * @param Cache $cache
+     * @return Configuration
+     */
+    static public function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
+    {
+        $config = self::createConfiguration($isDevMode, $proxyDir, $cache);
+        $config->setMetadataDriverImpl(new YamlDriver($paths));
+        return $config;
+    }
+
+    /**
+     * Create a configuration without a metadata driver.
+     *
+     * @param bool $isDevMode
+     * @param string $proxyDir
+     * @param Cache $cache
+     * @return Configuration
+     */
+    static public function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
+    {
+        $proxyDir = $proxyDir ?: sys_get_temp_dir();
+        if ($isDevMode === false && $cache === null) {
+            if (extension_loaded('apc')) {
+                $cache = new \Doctrine\Common\Cache\ApcCache;
+            } else if (extension_loaded('xcache')) {
+                $cache = new \Doctrine\Common\Cache\XcacheCache;
+            } else if (extension_loaded('memcache')) {
+                $memcache = new \Memcache();
+                $memcache->connect('127.0.0.1');
+                $cache = new \Doctrine\Common\Cache\MemcacheCache();
+                $cache->setMemcache($memcache);
+            } else {
+                $cache = new ArrayCache;
+            }
+        } else if ($cache === null) {
+            $cache = new ArrayCache;
+        }
+        $cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
+
+        $config = new Configuration();
+        $config->setMetadataCacheImpl($cache);
+        $config->setQueryCacheImpl($cache);
+        $config->setResultCacheImpl($cache);
+        $config->setProxyDir( $proxyDir );
+        $config->setProxyNamespace('DoctrineProxies');
+        $config->setAutoGenerateProxyClasses($isDevMode);
+
+        return $config;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolEvents.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolEvents.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolEvents.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM\Tools;
+
+class ToolEvents
+{
+    /**
+     * The postGenerateSchemaTable event occurs in SchemaTool#getSchemaFromMetadata()
+     * whenever an entity class is transformed into its table representation. It recieves
+     * the current non-complete Schema instance, the Entity Metadata Class instance and
+     * the Schema Table instance of this entity.
+     *
+     * @var string
+     */
+    const postGenerateSchemaTable = 'postGenerateSchemaTable';
+
+    /**
+     * The postGenerateSchema event is triggered in SchemaTool#getSchemaFromMetadata()
+     * after all entity classes have been transformed into the related Schema structure.
+     * The EventArgs contain the EntityManager and the created Schema instance.
+     *
+     * @var string
+     */
+    const postGenerateSchema = 'postGenerateSchema';
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolsException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolsException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ToolsException.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Tools;
+
+use Doctrine\ORM\ORMException;
+
+/**
+ * Tools related Exceptions
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ToolsException extends ORMException
+{
+    public static function schemaToolFailure($sql, \Exception $e)
+    {
+        return new self("Schema-Tool failed with Error '" . $e->getMessage() . "' while executing DDL: " . $sql, "0", $e);
+    }
+
+    public static function couldNotMapDoctrine1Type($type)
+    {
+        return new self("Could not map doctrine 1 type '$type'!");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/TransactionRequiredException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/TransactionRequiredException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/TransactionRequiredException.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\ORM;
+
+/**
+ * Is thrown when a transaction is required for the current operation, but there is none open.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class TransactionRequiredException extends ORMException
+{
+    static public function transactionRequired()
+    {
+        return new self('An open transaction is required for this operation.');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/UnitOfWork.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/UnitOfWork.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/UnitOfWork.php	(revision 345)
@@ -0,0 +1,2954 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+use Exception, InvalidArgumentException, UnexpectedValueException,
+    Doctrine\Common\Collections\ArrayCollection,
+    Doctrine\Common\Collections\Collection,
+    Doctrine\Common\NotifyPropertyChanged,
+    Doctrine\Common\PropertyChangedListener,
+    Doctrine\Common\Persistence\ObjectManagerAware,
+    Doctrine\ORM\Event\LifecycleEventArgs,
+    Doctrine\ORM\Mapping\ClassMetadata,
+    Doctrine\ORM\Proxy\Proxy;
+
+/**
+ * The UnitOfWork is responsible for tracking changes to objects during an
+ * "object-level" transaction and for writing out changes to the database
+ * in the correct order.
+ *
+ * @since       2.0
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ * @internal    This class contains highly performance-sensitive code.
+ */
+class UnitOfWork implements PropertyChangedListener
+{
+    /**
+     * An entity is in MANAGED state when its persistence is managed by an EntityManager.
+     */
+    const STATE_MANAGED = 1;
+
+    /**
+     * An entity is new if it has just been instantiated (i.e. using the "new" operator)
+     * and is not (yet) managed by an EntityManager.
+     */
+    const STATE_NEW = 2;
+
+    /**
+     * A detached entity is an instance with persistent state and identity that is not
+     * (or no longer) associated with an EntityManager (and a UnitOfWork).
+     */
+    const STATE_DETACHED = 3;
+
+    /**
+     * A removed entity instance is an instance with a persistent identity,
+     * associated with an EntityManager, whose persistent state will be deleted
+     * on commit.
+     */
+    const STATE_REMOVED = 4;
+
+    /**
+     * The identity map that holds references to all managed entities that have
+     * an identity. The entities are grouped by their class name.
+     * Since all classes in a hierarchy must share the same identifier set,
+     * we always take the root class name of the hierarchy.
+     *
+     * @var array
+     */
+    private $identityMap = array();
+
+    /**
+     * Map of all identifiers of managed entities.
+     * Keys are object ids (spl_object_hash).
+     *
+     * @var array
+     */
+    private $entityIdentifiers = array();
+
+    /**
+     * Map of the original entity data of managed entities.
+     * Keys are object ids (spl_object_hash). This is used for calculating changesets
+     * at commit time.
+     *
+     * @var array
+     * @internal Note that PHPs "copy-on-write" behavior helps a lot with memory usage.
+     *           A value will only really be copied if the value in the entity is modified
+     *           by the user.
+     */
+    private $originalEntityData = array();
+
+    /**
+     * Map of entity changes. Keys are object ids (spl_object_hash).
+     * Filled at the beginning of a commit of the UnitOfWork and cleaned at the end.
+     *
+     * @var array
+     */
+    private $entityChangeSets = array();
+
+    /**
+     * The (cached) states of any known entities.
+     * Keys are object ids (spl_object_hash).
+     *
+     * @var array
+     */
+    private $entityStates = array();
+
+    /**
+     * Map of entities that are scheduled for dirty checking at commit time.
+     * This is only used for entities with a change tracking policy of DEFERRED_EXPLICIT.
+     * Keys are object ids (spl_object_hash).
+     *
+     * @var array
+     * @todo rename: scheduledForSynchronization
+     */
+    private $scheduledForDirtyCheck = array();
+
+    /**
+     * A list of all pending entity insertions.
+     *
+     * @var array
+     */
+    private $entityInsertions = array();
+
+    /**
+     * A list of all pending entity updates.
+     *
+     * @var array
+     */
+    private $entityUpdates = array();
+
+    /**
+     * Any pending extra updates that have been scheduled by persisters.
+     *
+     * @var array
+     */
+    private $extraUpdates = array();
+
+    /**
+     * A list of all pending entity deletions.
+     *
+     * @var array
+     */
+    private $entityDeletions = array();
+
+    /**
+     * All pending collection deletions.
+     *
+     * @var array
+     */
+    private $collectionDeletions = array();
+
+    /**
+     * All pending collection updates.
+     *
+     * @var array
+     */
+    private $collectionUpdates = array();
+
+    /**
+     * List of collections visited during changeset calculation on a commit-phase of a UnitOfWork.
+     * At the end of the UnitOfWork all these collections will make new snapshots
+     * of their data.
+     *
+     * @var array
+     */
+    private $visitedCollections = array();
+
+    /**
+     * The EntityManager that "owns" this UnitOfWork instance.
+     *
+     * @var \Doctrine\ORM\EntityManager
+     */
+    private $em;
+
+    /**
+     * The calculator used to calculate the order in which changes to
+     * entities need to be written to the database.
+     *
+     * @var \Doctrine\ORM\Internal\CommitOrderCalculator
+     */
+    private $commitOrderCalculator;
+
+    /**
+     * The entity persister instances used to persist entity instances.
+     *
+     * @var array
+     */
+    private $persisters = array();
+
+    /**
+     * The collection persister instances used to persist collections.
+     *
+     * @var array
+     */
+    private $collectionPersisters = array();
+
+    /**
+     * The EventManager used for dispatching events.
+     *
+     * @var EventManager
+     */
+    private $evm;
+
+    /**
+     * Orphaned entities that are scheduled for removal.
+     *
+     * @var array
+     */
+    private $orphanRemovals = array();
+
+    /**
+     * Read-Only objects are never evaluated
+     *
+     * @var array
+     */
+    private $readOnlyObjects = array();
+
+    /**
+     * Map of Entity Class-Names and corresponding IDs that should eager loaded when requested.
+     *
+     * @var array
+     */
+    private $eagerLoadingEntities = array();
+
+    /**
+     * Initializes a new UnitOfWork instance, bound to the given EntityManager.
+     *
+     * @param \Doctrine\ORM\EntityManager $em
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+        $this->evm = $em->getEventManager();
+    }
+
+    /**
+     * Commits the UnitOfWork, executing all operations that have been postponed
+     * up to this point. The state of all managed entities will be synchronized with
+     * the database.
+     *
+     * The operations are executed in the following order:
+     *
+     * 1) All entity insertions
+     * 2) All entity updates
+     * 3) All collection deletions
+     * 4) All collection updates
+     * 5) All entity deletions
+     *
+     * @param object $entity
+     * @return void
+     */
+    public function commit($entity = null)
+    {
+        // Raise preFlush
+        if ($this->evm->hasListeners(Events::preFlush)) {
+            $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->em));
+        }
+
+        // Compute changes done since last commit.
+        if ($entity === null) {
+            $this->computeChangeSets();
+        } else {
+            $this->computeSingleEntityChangeSet($entity);
+        }
+
+        if ( ! ($this->entityInsertions ||
+                $this->entityDeletions ||
+                $this->entityUpdates ||
+                $this->collectionUpdates ||
+                $this->collectionDeletions ||
+                $this->orphanRemovals)) {
+            return; // Nothing to do.
+        }
+
+        if ($this->orphanRemovals) {
+            foreach ($this->orphanRemovals as $orphan) {
+                $this->remove($orphan);
+            }
+        }
+
+        // Raise onFlush
+        if ($this->evm->hasListeners(Events::onFlush)) {
+            $this->evm->dispatchEvent(Events::onFlush, new Event\OnFlushEventArgs($this->em));
+        }
+
+        // Now we need a commit order to maintain referential integrity
+        $commitOrder = $this->getCommitOrder();
+
+        $conn = $this->em->getConnection();
+        $conn->beginTransaction();
+
+        try {
+            if ($this->entityInsertions) {
+                foreach ($commitOrder as $class) {
+                    $this->executeInserts($class);
+                }
+            }
+
+            if ($this->entityUpdates) {
+                foreach ($commitOrder as $class) {
+                    $this->executeUpdates($class);
+                }
+            }
+
+            // Extra updates that were requested by persisters.
+            if ($this->extraUpdates) {
+                $this->executeExtraUpdates();
+            }
+
+            // Collection deletions (deletions of complete collections)
+            foreach ($this->collectionDeletions as $collectionToDelete) {
+                $this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete);
+            }
+            // Collection updates (deleteRows, updateRows, insertRows)
+            foreach ($this->collectionUpdates as $collectionToUpdate) {
+                $this->getCollectionPersister($collectionToUpdate->getMapping())->update($collectionToUpdate);
+            }
+
+            // Entity deletions come last and need to be in reverse commit order
+            if ($this->entityDeletions) {
+                for ($count = count($commitOrder), $i = $count - 1; $i >= 0; --$i) {
+                    $this->executeDeletions($commitOrder[$i]);
+                }
+            }
+
+            $conn->commit();
+        } catch (Exception $e) {
+            $this->em->close();
+            $conn->rollback();
+
+            throw $e;
+        }
+
+        // Take new snapshots from visited collections
+        foreach ($this->visitedCollections as $coll) {
+            $coll->takeSnapshot();
+        }
+
+        // Raise postFlush
+        if ($this->evm->hasListeners(Events::postFlush)) {
+            $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->em));
+        }
+
+        // Clear up
+        $this->entityInsertions =
+        $this->entityUpdates =
+        $this->entityDeletions =
+        $this->extraUpdates =
+        $this->entityChangeSets =
+        $this->collectionUpdates =
+        $this->collectionDeletions =
+        $this->visitedCollections =
+        $this->scheduledForDirtyCheck =
+        $this->orphanRemovals = array();
+    }
+
+    /**
+     * Compute the changesets of all entities scheduled for insertion
+     *
+     * @return void
+     */
+    private function computeScheduleInsertsChangeSets()
+    {
+        foreach ($this->entityInsertions as $entity) {
+            $class = $this->em->getClassMetadata(get_class($entity));
+
+            $this->computeChangeSet($class, $entity);
+        }
+    }
+
+    /**
+     * Only flush the given entity according to a ruleset that keeps the UoW consistent.
+     *
+     * 1. All entities scheduled for insertion, (orphan) removals and changes in collections are processed as well!
+     * 2. Read Only entities are skipped.
+     * 3. Proxies are skipped.
+     * 4. Only if entity is properly managed.
+     *
+     * @param  object $entity
+     * @return void
+     */
+    private function computeSingleEntityChangeSet($entity)
+    {
+        if ( $this->getEntityState($entity) !== self::STATE_MANAGED) {
+            throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity));
+        }
+
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        if ($class->isChangeTrackingDeferredImplicit()) {
+            $this->persist($entity);
+        }
+
+        // Compute changes for INSERTed entities first. This must always happen even in this case.
+        $this->computeScheduleInsertsChangeSets();
+
+        if ($class->isReadOnly) {
+            return;
+        }
+
+        // Ignore uninitialized proxy objects
+        if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
+            return;
+        }
+
+        // Only MANAGED entities that are NOT SCHEDULED FOR INSERTION are processed here.
+        $oid = spl_object_hash($entity);
+
+        if ( ! isset($this->entityInsertions[$oid]) && isset($this->entityStates[$oid])) {
+            $this->computeChangeSet($class, $entity);
+        }
+    }
+
+    /**
+     * Executes any extra updates that have been scheduled.
+     */
+    private function executeExtraUpdates()
+    {
+        foreach ($this->extraUpdates as $oid => $update) {
+            list ($entity, $changeset) = $update;
+
+            $this->entityChangeSets[$oid] = $changeset;
+            $this->getEntityPersister(get_class($entity))->update($entity);
+        }
+    }
+
+    /**
+     * Gets the changeset for an entity.
+     *
+     * @return array
+     */
+    public function getEntityChangeSet($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->entityChangeSets[$oid])) {
+            return $this->entityChangeSets[$oid];
+        }
+
+        return array();
+    }
+
+    /**
+     * Computes the changes that happened to a single entity.
+     *
+     * Modifies/populates the following properties:
+     *
+     * {@link _originalEntityData}
+     * If the entity is NEW or MANAGED but not yet fully persisted (only has an id)
+     * then it was not fetched from the database and therefore we have no original
+     * entity data yet. All of the current entity data is stored as the original entity data.
+     *
+     * {@link _entityChangeSets}
+     * The changes detected on all properties of the entity are stored there.
+     * A change is a tuple array where the first entry is the old value and the second
+     * entry is the new value of the property. Changesets are used by persisters
+     * to INSERT/UPDATE the persistent entity state.
+     *
+     * {@link _entityUpdates}
+     * If the entity is already fully MANAGED (has been fetched from the database before)
+     * and any changes to its properties are detected, then a reference to the entity is stored
+     * there to mark it for an update.
+     *
+     * {@link _collectionDeletions}
+     * If a PersistentCollection has been de-referenced in a fully MANAGED entity,
+     * then this collection is marked for deletion.
+     *
+     * @ignore
+     * @internal Don't call from the outside.
+     * @param ClassMetadata $class The class descriptor of the entity.
+     * @param object $entity The entity for which to compute the changes.
+     */
+    public function computeChangeSet(ClassMetadata $class, $entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->readOnlyObjects[$oid])) {
+            return;
+        }
+
+        if ( ! $class->isInheritanceTypeNone()) {
+            $class = $this->em->getClassMetadata(get_class($entity));
+        }
+
+        // Fire PreFlush lifecycle callbacks
+        if (isset($class->lifecycleCallbacks[Events::preFlush])) {
+            $class->invokeLifecycleCallbacks(Events::preFlush, $entity);
+        }
+
+        $actualData = array();
+
+        foreach ($class->reflFields as $name => $refProp) {
+            $value = $refProp->getValue($entity);
+
+            if ($class->isCollectionValuedAssociation($name) && $value !== null && ! ($value instanceof PersistentCollection)) {
+                // If $value is not a Collection then use an ArrayCollection.
+                if ( ! $value instanceof Collection) {
+                    $value = new ArrayCollection($value);
+                }
+
+                $assoc = $class->associationMappings[$name];
+
+                // Inject PersistentCollection
+                $value = new PersistentCollection(
+                    $this->em, $this->em->getClassMetadata($assoc['targetEntity']), $value
+                );
+                $value->setOwner($entity, $assoc);
+                $value->setDirty( ! $value->isEmpty());
+
+                $class->reflFields[$name]->setValue($entity, $value);
+
+                $actualData[$name] = $value;
+
+                continue;
+            }
+
+            if (( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) && ($name !== $class->versionField)) {
+                $actualData[$name] = $value;
+            }
+        }
+
+        if ( ! isset($this->originalEntityData[$oid])) {
+            // Entity is either NEW or MANAGED but not yet fully persisted (only has an id).
+            // These result in an INSERT.
+            $this->originalEntityData[$oid] = $actualData;
+            $changeSet = array();
+
+            foreach ($actualData as $propName => $actualValue) {
+                if ( ! isset($class->associationMappings[$propName])) {
+                    $changeSet[$propName] = array(null, $actualValue);
+
+                    continue;
+                }
+
+                $assoc = $class->associationMappings[$propName];
+
+                if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
+                    $changeSet[$propName] = array(null, $actualValue);
+                }
+            }
+
+            $this->entityChangeSets[$oid] = $changeSet;
+        } else {
+            // Entity is "fully" MANAGED: it was already fully persisted before
+            // and we have a copy of the original data
+            $originalData           = $this->originalEntityData[$oid];
+            $isChangeTrackingNotify = $class->isChangeTrackingNotify();
+            $changeSet              = ($isChangeTrackingNotify && isset($this->entityChangeSets[$oid]))
+                ? $this->entityChangeSets[$oid]
+                : array();
+
+            foreach ($actualData as $propName => $actualValue) {
+                // skip field, its a partially omitted one!
+                if ( ! (isset($originalData[$propName]) || array_key_exists($propName, $originalData))) {
+                    continue;
+                }
+
+                $orgValue = $originalData[$propName];
+
+                // skip if value havent changed
+                if ($orgValue === $actualValue) {
+                    continue;
+                }
+
+                // if regular field
+                if ( ! isset($class->associationMappings[$propName])) {
+                    if ($isChangeTrackingNotify) {
+                        continue;
+                    }
+
+                    $changeSet[$propName] = array($orgValue, $actualValue);
+
+                    continue;
+                }
+
+                $assoc = $class->associationMappings[$propName];
+
+                // Persistent collection was exchanged with the "originally"
+                // created one. This can only mean it was cloned and replaced
+                // on another entity.
+                if ($actualValue instanceof PersistentCollection) {
+                    $owner = $actualValue->getOwner();
+                    if ($owner === null) { // cloned
+                        $actualValue->setOwner($entity, $assoc);
+                    } else if ($owner !== $entity) { // no clone, we have to fix
+                        if (!$actualValue->isInitialized()) {
+                            $actualValue->initialize(); // we have to do this otherwise the cols share state
+                        }
+                        $newValue = clone $actualValue;
+                        $newValue->setOwner($entity, $assoc);
+                        $class->reflFields[$propName]->setValue($entity, $newValue);
+                    }
+                }
+
+                if ($orgValue instanceof PersistentCollection) {
+                    // A PersistentCollection was de-referenced, so delete it.
+                    $coid = spl_object_hash($orgValue);
+
+                    if (isset($this->collectionDeletions[$coid])) {
+                        continue;
+                    }
+
+                    $this->collectionDeletions[$coid] = $orgValue;
+                    $changeSet[$propName] = $orgValue; // Signal changeset, to-many assocs will be ignored.
+
+                    continue;
+                }
+
+                if ($assoc['type'] & ClassMetadata::TO_ONE) {
+                    if ($assoc['isOwningSide']) {
+                        $changeSet[$propName] = array($orgValue, $actualValue);
+                    }
+
+                    if ($orgValue !== null && $assoc['orphanRemoval']) {
+                        $this->scheduleOrphanRemoval($orgValue);
+                    }
+                }
+            }
+
+            if ($changeSet) {
+                $this->entityChangeSets[$oid]   = $changeSet;
+                $this->originalEntityData[$oid] = $actualData;
+                $this->entityUpdates[$oid]      = $entity;
+            }
+        }
+
+        // Look for changes in associations of the entity
+        foreach ($class->associationMappings as $field => $assoc) {
+            if (($val = $class->reflFields[$field]->getValue($entity)) !== null) {
+                $this->computeAssociationChanges($assoc, $val);
+                if (!isset($this->entityChangeSets[$oid]) &&
+                    $assoc['isOwningSide'] &&
+                    $assoc['type'] == ClassMetadata::MANY_TO_MANY &&
+                    $val instanceof PersistentCollection &&
+                    $val->isDirty()) {
+                    $this->entityChangeSets[$oid]   = array();
+                    $this->originalEntityData[$oid] = $actualData;
+                    $this->entityUpdates[$oid]      = $entity;
+                }
+            }
+        }
+    }
+
+    /**
+     * Computes all the changes that have been done to entities and collections
+     * since the last commit and stores these changes in the _entityChangeSet map
+     * temporarily for access by the persisters, until the UoW commit is finished.
+     */
+    public function computeChangeSets()
+    {
+        // Compute changes for INSERTed entities first. This must always happen.
+        $this->computeScheduleInsertsChangeSets();
+
+        // Compute changes for other MANAGED entities. Change tracking policies take effect here.
+        foreach ($this->identityMap as $className => $entities) {
+            $class = $this->em->getClassMetadata($className);
+
+            // Skip class if instances are read-only
+            if ($class->isReadOnly) {
+                continue;
+            }
+
+            // If change tracking is explicit or happens through notification, then only compute
+            // changes on entities of that type that are explicitly marked for synchronization.
+            switch (true) {
+                case ($class->isChangeTrackingDeferredImplicit()):
+                    $entitiesToProcess = $entities;
+                    break;
+
+                case (isset($this->scheduledForDirtyCheck[$className])):
+                    $entitiesToProcess = $this->scheduledForDirtyCheck[$className];
+                    break;
+
+                default:
+                    $entitiesToProcess = array();
+
+            }
+
+            foreach ($entitiesToProcess as $entity) {
+                // Ignore uninitialized proxy objects
+                if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
+                    continue;
+                }
+
+                // Only MANAGED entities that are NOT SCHEDULED FOR INSERTION are processed here.
+                $oid = spl_object_hash($entity);
+
+                if ( ! isset($this->entityInsertions[$oid]) && isset($this->entityStates[$oid])) {
+                    $this->computeChangeSet($class, $entity);
+                }
+            }
+        }
+    }
+
+    /**
+     * Computes the changes of an association.
+     *
+     * @param AssociationMapping $assoc
+     * @param mixed $value The value of the association.
+     */
+    private function computeAssociationChanges($assoc, $value)
+    {
+        if ($value instanceof Proxy && ! $value->__isInitialized__) {
+            return;
+        }
+
+        if ($value instanceof PersistentCollection && $value->isDirty()) {
+            $coid = spl_object_hash($value);
+
+            if ($assoc['isOwningSide']) {
+                $this->collectionUpdates[$coid] = $value;
+            }
+
+            $this->visitedCollections[$coid] = $value;
+        }
+
+        // Look through the entities, and in any of their associations,
+        // for transient (new) entities, recursively. ("Persistence by reachability")
+        // Unwrap. Uninitialized collections will simply be empty.
+        $unwrappedValue = ($assoc['type'] & ClassMetadata::TO_ONE) ? array($value) : $value->unwrap();
+        $targetClass    = $this->em->getClassMetadata($assoc['targetEntity']);
+
+        foreach ($unwrappedValue as $key => $entry) {
+            $state = $this->getEntityState($entry, self::STATE_NEW);
+            $oid   = spl_object_hash($entry);
+
+            if (!($entry instanceof $assoc['targetEntity'])) {
+                throw new ORMException(sprintf("Found entity of type %s on association %s#%s, but expecting %s",
+                    get_class($entry),
+                    $assoc['sourceEntity'],
+                    $assoc['fieldName'],
+                    $targetClass->name
+                ));
+            }
+
+            switch ($state) {
+                case self::STATE_NEW:
+                    if ( ! $assoc['isCascadePersist']) {
+                        throw ORMInvalidArgumentException::newEntityFoundThroughRelationship($assoc, $entry);
+                    }
+
+                    $this->persistNew($targetClass, $entry);
+                    $this->computeChangeSet($targetClass, $entry);
+                    break;
+
+                case self::STATE_REMOVED:
+                    // Consume the $value as array (it's either an array or an ArrayAccess)
+                    // and remove the element from Collection.
+                    if ($assoc['type'] & ClassMetadata::TO_MANY) {
+                        unset($value[$key]);
+                    }
+                    break;
+
+                case self::STATE_DETACHED:
+                    // Can actually not happen right now as we assume STATE_NEW,
+                    // so the exception will be raised from the DBAL layer (constraint violation).
+                    throw ORMInvalidArgumentException::detachedEntityFoundThroughRelationship($assoc, $entry);
+                    break;
+
+                default:
+                    // MANAGED associated entities are already taken into account
+                    // during changeset calculation anyway, since they are in the identity map.
+            }
+        }
+    }
+
+    private function persistNew($class, $entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($class->lifecycleCallbacks[Events::prePersist])) {
+            $class->invokeLifecycleCallbacks(Events::prePersist, $entity);
+        }
+
+        if ($this->evm->hasListeners(Events::prePersist)) {
+            $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity, $this->em));
+        }
+
+        $idGen = $class->idGenerator;
+
+        if ( ! $idGen->isPostInsertGenerator()) {
+            $idValue = $idGen->generate($this->em, $entity);
+
+            if ( ! $idGen instanceof \Doctrine\ORM\Id\AssignedGenerator) {
+                $idValue = array($class->identifier[0] => $idValue);
+
+                $class->setIdentifierValues($entity, $idValue);
+            }
+
+            $this->entityIdentifiers[$oid] = $idValue;
+        }
+
+        $this->entityStates[$oid] = self::STATE_MANAGED;
+
+        $this->scheduleForInsert($entity);
+    }
+
+    /**
+     * INTERNAL:
+     * Computes the changeset of an individual entity, independently of the
+     * computeChangeSets() routine that is used at the beginning of a UnitOfWork#commit().
+     *
+     * The passed entity must be a managed entity. If the entity already has a change set
+     * because this method is invoked during a commit cycle then the change sets are added.
+     * whereby changes detected in this method prevail.
+     *
+     * @ignore
+     * @param ClassMetadata $class The class descriptor of the entity.
+     * @param object $entity The entity for which to (re)calculate the change set.
+     * @throws InvalidArgumentException If the passed entity is not MANAGED.
+     */
+    public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if ( ! isset($this->entityStates[$oid]) || $this->entityStates[$oid] != self::STATE_MANAGED) {
+            throw ORMInvalidArgumentException::entityNotManaged($entity);
+        }
+
+        // skip if change tracking is "NOTIFY"
+        if ($class->isChangeTrackingNotify()) {
+            return;
+        }
+
+        if ( ! $class->isInheritanceTypeNone()) {
+            $class = $this->em->getClassMetadata(get_class($entity));
+        }
+
+        $actualData = array();
+
+        foreach ($class->reflFields as $name => $refProp) {
+            if ( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) {
+                $actualData[$name] = $refProp->getValue($entity);
+            }
+        }
+
+        $originalData = $this->originalEntityData[$oid];
+        $changeSet = array();
+
+        foreach ($actualData as $propName => $actualValue) {
+            $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
+
+            if (is_object($orgValue) && $orgValue !== $actualValue) {
+                $changeSet[$propName] = array($orgValue, $actualValue);
+            } else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) {
+                $changeSet[$propName] = array($orgValue, $actualValue);
+            }
+        }
+
+        if ($changeSet) {
+            if (isset($this->entityChangeSets[$oid])) {
+                $this->entityChangeSets[$oid] = array_merge($this->entityChangeSets[$oid], $changeSet);
+            }
+
+            $this->originalEntityData[$oid] = $actualData;
+        }
+    }
+
+    /**
+     * Executes all entity insertions for entities of the specified type.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     */
+    private function executeInserts($class)
+    {
+        $className = $class->name;
+        $persister = $this->getEntityPersister($className);
+        $entities  = array();
+
+        $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]);
+        $hasListeners          = $this->evm->hasListeners(Events::postPersist);
+
+        foreach ($this->entityInsertions as $oid => $entity) {
+            if (get_class($entity) !== $className) {
+                continue;
+            }
+
+            $persister->addInsert($entity);
+
+            unset($this->entityInsertions[$oid]);
+
+            if ($hasLifecycleCallbacks || $hasListeners) {
+                $entities[] = $entity;
+            }
+        }
+
+        $postInsertIds = $persister->executeInserts();
+
+        if ($postInsertIds) {
+            // Persister returned post-insert IDs
+            foreach ($postInsertIds as $id => $entity) {
+                $oid     = spl_object_hash($entity);
+                $idField = $class->identifier[0];
+
+                $class->reflFields[$idField]->setValue($entity, $id);
+
+                $this->entityIdentifiers[$oid] = array($idField => $id);
+                $this->entityStates[$oid] = self::STATE_MANAGED;
+                $this->originalEntityData[$oid][$idField] = $id;
+
+                $this->addToIdentityMap($entity);
+            }
+        }
+
+        foreach ($entities as $entity) {
+            if ($hasLifecycleCallbacks) {
+                $class->invokeLifecycleCallbacks(Events::postPersist, $entity);
+            }
+
+            if ($hasListeners) {
+                $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity, $this->em));
+            }
+        }
+    }
+
+    /**
+     * Executes all entity updates for entities of the specified type.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     */
+    private function executeUpdates($class)
+    {
+        $className = $class->name;
+        $persister = $this->getEntityPersister($className);
+
+        $hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]);
+        $hasPreUpdateListeners          = $this->evm->hasListeners(Events::preUpdate);
+
+        $hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]);
+        $hasPostUpdateListeners          = $this->evm->hasListeners(Events::postUpdate);
+
+        foreach ($this->entityUpdates as $oid => $entity) {
+            if ( ! (get_class($entity) === $className || $entity instanceof Proxy && get_parent_class($entity) === $className)) {
+                continue;
+            }
+
+            if ($hasPreUpdateLifecycleCallbacks) {
+                $class->invokeLifecycleCallbacks(Events::preUpdate, $entity);
+
+                $this->recomputeSingleEntityChangeSet($class, $entity);
+            }
+
+            if ($hasPreUpdateListeners) {
+                $this->evm->dispatchEvent(
+                    Events::preUpdate,
+                    new Event\PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid])
+                );
+            }
+
+            if ($this->entityChangeSets[$oid]) {
+                $persister->update($entity);
+            }
+
+            unset($this->entityUpdates[$oid]);
+
+            if ($hasPostUpdateLifecycleCallbacks) {
+                $class->invokeLifecycleCallbacks(Events::postUpdate, $entity);
+            }
+
+            if ($hasPostUpdateListeners) {
+                $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity, $this->em));
+            }
+        }
+    }
+
+    /**
+     * Executes all entity deletions for entities of the specified type.
+     *
+     * @param \Doctrine\ORM\Mapping\ClassMetadata $class
+     */
+    private function executeDeletions($class)
+    {
+        $className = $class->name;
+        $persister = $this->getEntityPersister($className);
+
+        $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]);
+        $hasListeners = $this->evm->hasListeners(Events::postRemove);
+
+        foreach ($this->entityDeletions as $oid => $entity) {
+            if ( ! (get_class($entity) == $className || $entity instanceof Proxy && get_parent_class($entity) == $className)) {
+                continue;
+            }
+
+            $persister->delete($entity);
+
+            unset(
+                $this->entityDeletions[$oid],
+                $this->entityIdentifiers[$oid],
+                $this->originalEntityData[$oid],
+                $this->entityStates[$oid]
+            );
+
+            // Entity with this $oid after deletion treated as NEW, even if the $oid
+            // is obtained by a new entity because the old one went out of scope.
+            //$this->entityStates[$oid] = self::STATE_NEW;
+            if ( ! $class->isIdentifierNatural()) {
+                $class->reflFields[$class->identifier[0]]->setValue($entity, null);
+            }
+
+            if ($hasLifecycleCallbacks) {
+                $class->invokeLifecycleCallbacks(Events::postRemove, $entity);
+            }
+
+            if ($hasListeners) {
+                $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity, $this->em));
+            }
+        }
+    }
+
+    /**
+     * Gets the commit order.
+     *
+     * @return array
+     */
+    private function getCommitOrder(array $entityChangeSet = null)
+    {
+        if ($entityChangeSet === null) {
+            $entityChangeSet = array_merge($this->entityInsertions, $this->entityUpdates, $this->entityDeletions);
+        }
+
+        $calc = $this->getCommitOrderCalculator();
+
+        // See if there are any new classes in the changeset, that are not in the
+        // commit order graph yet (dont have a node).
+        // We have to inspect changeSet to be able to correctly build dependencies.
+        // It is not possible to use IdentityMap here because post inserted ids
+        // are not yet available.
+        $newNodes = array();
+
+        foreach ($entityChangeSet as $oid => $entity) {
+            $className = get_class($entity);
+
+            if ($calc->hasClass($className)) {
+                continue;
+            }
+
+            $class = $this->em->getClassMetadata($className);
+            $calc->addClass($class);
+
+            $newNodes[] = $class;
+        }
+
+        // Calculate dependencies for new nodes
+        while ($class = array_pop($newNodes)) {
+            foreach ($class->associationMappings as $assoc) {
+                if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) {
+                    continue;
+                }
+
+                $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
+
+                if ( ! $calc->hasClass($targetClass->name)) {
+                    $calc->addClass($targetClass);
+
+                    $newNodes[] = $targetClass;
+                }
+
+                $calc->addDependency($targetClass, $class);
+
+                // If the target class has mapped subclasses, these share the same dependency.
+                if ( ! $targetClass->subClasses) {
+                    continue;
+                }
+
+                foreach ($targetClass->subClasses as $subClassName) {
+                    $targetSubClass = $this->em->getClassMetadata($subClassName);
+
+                    if ( ! $calc->hasClass($subClassName)) {
+                        $calc->addClass($targetSubClass);
+
+                        $newNodes[] = $targetSubClass;
+                    }
+
+                    $calc->addDependency($targetSubClass, $class);
+                }
+            }
+        }
+
+        return $calc->getCommitOrder();
+    }
+
+    /**
+     * Schedules an entity for insertion into the database.
+     * If the entity already has an identifier, it will be added to the identity map.
+     *
+     * @param object $entity The entity to schedule for insertion.
+     */
+    public function scheduleForInsert($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->entityUpdates[$oid])) {
+            throw new InvalidArgumentException("Dirty entity can not be scheduled for insertion.");
+        }
+
+        if (isset($this->entityDeletions[$oid])) {
+            throw ORMInvalidArgumentException::scheduleInsertForRemovedEntity($entity);
+        }
+        if (isset($this->originalEntityData[$oid]) && ! isset($this->entityInsertions[$oid])) {
+            throw ORMInvalidArgumentException::scheduleInsertForManagedEntity($entity);
+        }
+
+        if (isset($this->entityInsertions[$oid])) {
+            throw ORMInvalidArgumentException::scheduleInsertTwice($entity);
+        }
+
+        $this->entityInsertions[$oid] = $entity;
+
+        if (isset($this->entityIdentifiers[$oid])) {
+            $this->addToIdentityMap($entity);
+        }
+
+        if ($entity instanceof NotifyPropertyChanged) {
+            $entity->addPropertyChangedListener($this);
+        }
+    }
+
+    /**
+     * Checks whether an entity is scheduled for insertion.
+     *
+     * @param object $entity
+     * @return boolean
+     */
+    public function isScheduledForInsert($entity)
+    {
+        return isset($this->entityInsertions[spl_object_hash($entity)]);
+    }
+
+    /**
+     * Schedules an entity for being updated.
+     *
+     * @param object $entity The entity to schedule for being updated.
+     */
+    public function scheduleForUpdate($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if ( ! isset($this->entityIdentifiers[$oid])) {
+            throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "scheduling for update");
+        }
+
+        if (isset($this->entityDeletions[$oid])) {
+            throw ORMInvalidArgumentException::entityIsRemoved($entity, "schedule for update");
+        }
+
+        if ( ! isset($this->entityUpdates[$oid]) && ! isset($this->entityInsertions[$oid])) {
+            $this->entityUpdates[$oid] = $entity;
+        }
+    }
+
+    /**
+     * INTERNAL:
+     * Schedules an extra update that will be executed immediately after the
+     * regular entity updates within the currently running commit cycle.
+     *
+     * Extra updates for entities are stored as (entity, changeset) tuples.
+     *
+     * @ignore
+     * @param object $entity The entity for which to schedule an extra update.
+     * @param array $changeset The changeset of the entity (what to update).
+     */
+    public function scheduleExtraUpdate($entity, array $changeset)
+    {
+        $oid         = spl_object_hash($entity);
+        $extraUpdate = array($entity, $changeset);
+
+        if (isset($this->extraUpdates[$oid])) {
+            list($ignored, $changeset2) = $this->extraUpdates[$oid];
+
+            $extraUpdate = array($entity, $changeset + $changeset2);
+        }
+
+        $this->extraUpdates[$oid] = $extraUpdate;
+    }
+
+    /**
+     * Checks whether an entity is registered as dirty in the unit of work.
+     * Note: Is not very useful currently as dirty entities are only registered
+     * at commit time.
+     *
+     * @param object $entity
+     * @return boolean
+     */
+    public function isScheduledForUpdate($entity)
+    {
+        return isset($this->entityUpdates[spl_object_hash($entity)]);
+    }
+
+
+    /**
+     * Checks whether an entity is registered to be checked in the unit of work.
+     *
+     * @param object $entity
+     * @return boolean
+     */
+    public function isScheduledForDirtyCheck($entity)
+    {
+        $rootEntityName = $this->em->getClassMetadata(get_class($entity))->rootEntityName;
+
+        return isset($this->scheduledForDirtyCheck[$rootEntityName][spl_object_hash($entity)]);
+    }
+
+    /**
+     * INTERNAL:
+     * Schedules an entity for deletion.
+     *
+     * @param object $entity
+     */
+    public function scheduleForDelete($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->entityInsertions[$oid])) {
+            if ($this->isInIdentityMap($entity)) {
+                $this->removeFromIdentityMap($entity);
+            }
+
+            unset($this->entityInsertions[$oid], $this->entityStates[$oid]);
+
+            return; // entity has not been persisted yet, so nothing more to do.
+        }
+
+        if ( ! $this->isInIdentityMap($entity)) {
+            return;
+        }
+
+        $this->removeFromIdentityMap($entity);
+
+        if (isset($this->entityUpdates[$oid])) {
+            unset($this->entityUpdates[$oid]);
+        }
+
+        if ( ! isset($this->entityDeletions[$oid])) {
+            $this->entityDeletions[$oid] = $entity;
+            $this->entityStates[$oid]    = self::STATE_REMOVED;
+        }
+    }
+
+    /**
+     * Checks whether an entity is registered as removed/deleted with the unit
+     * of work.
+     *
+     * @param object $entity
+     * @return boolean
+     */
+    public function isScheduledForDelete($entity)
+    {
+        return isset($this->entityDeletions[spl_object_hash($entity)]);
+    }
+
+    /**
+     * Checks whether an entity is scheduled for insertion, update or deletion.
+     *
+     * @param $entity
+     * @return boolean
+     */
+    public function isEntityScheduled($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        return isset($this->entityInsertions[$oid])
+            || isset($this->entityUpdates[$oid])
+            || isset($this->entityDeletions[$oid]);
+    }
+
+    /**
+     * INTERNAL:
+     * Registers an entity in the identity map.
+     * Note that entities in a hierarchy are registered with the class name of
+     * the root entity.
+     *
+     * @ignore
+     * @param object $entity  The entity to register.
+     * @return boolean  TRUE if the registration was successful, FALSE if the identity of
+     *                  the entity in question is already managed.
+     */
+    public function addToIdentityMap($entity)
+    {
+        $classMetadata = $this->em->getClassMetadata(get_class($entity));
+        $idHash        = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]);
+
+        if ($idHash === '') {
+            throw ORMInvalidArgumentException::entityWithoutIdentity($classMetadata->name, $entity);
+        }
+
+        $className = $classMetadata->rootEntityName;
+
+        if (isset($this->identityMap[$className][$idHash])) {
+            return false;
+        }
+
+        $this->identityMap[$className][$idHash] = $entity;
+
+        return true;
+    }
+
+    /**
+     * Gets the state of an entity with regard to the current unit of work.
+     *
+     * @param object $entity
+     * @param integer $assume The state to assume if the state is not yet known (not MANAGED or REMOVED).
+     *                        This parameter can be set to improve performance of entity state detection
+     *                        by potentially avoiding a database lookup if the distinction between NEW and DETACHED
+     *                        is either known or does not matter for the caller of the method.
+     * @return int The entity state.
+     */
+    public function getEntityState($entity, $assume = null)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->entityStates[$oid])) {
+            return $this->entityStates[$oid];
+        }
+
+        if ($assume !== null) {
+            return $assume;
+        }
+
+        // State can only be NEW or DETACHED, because MANAGED/REMOVED states are known.
+        // Note that you can not remember the NEW or DETACHED state in _entityStates since
+        // the UoW does not hold references to such objects and the object hash can be reused.
+        // More generally because the state may "change" between NEW/DETACHED without the UoW being aware of it.
+        $class = $this->em->getClassMetadata(get_class($entity));
+        $id    = $class->getIdentifierValues($entity);
+
+        if ( ! $id) {
+            return self::STATE_NEW;
+        }
+
+        switch (true) {
+            case ($class->isIdentifierNatural());
+                // Check for a version field, if available, to avoid a db lookup.
+                if ($class->isVersioned) {
+                    return ($class->getFieldValue($entity, $class->versionField))
+                        ? self::STATE_DETACHED
+                        : self::STATE_NEW;
+                }
+
+                // Last try before db lookup: check the identity map.
+                if ($this->tryGetById($id, $class->rootEntityName)) {
+                    return self::STATE_DETACHED;
+                }
+
+                // db lookup
+                if ($this->getEntityPersister(get_class($entity))->exists($entity)) {
+                    return self::STATE_DETACHED;
+                }
+
+                return self::STATE_NEW;
+
+            case ( ! $class->idGenerator->isPostInsertGenerator()):
+                // if we have a pre insert generator we can't be sure that having an id
+                // really means that the entity exists. We have to verify this through
+                // the last resort: a db lookup
+
+                // Last try before db lookup: check the identity map.
+                if ($this->tryGetById($id, $class->rootEntityName)) {
+                    return self::STATE_DETACHED;
+                }
+
+                // db lookup
+                if ($this->getEntityPersister(get_class($entity))->exists($entity)) {
+                    return self::STATE_DETACHED;
+                }
+
+                return self::STATE_NEW;
+
+            default:
+                return self::STATE_DETACHED;
+        }
+    }
+
+    /**
+     * INTERNAL:
+     * Removes an entity from the identity map. This effectively detaches the
+     * entity from the persistence management of Doctrine.
+     *
+     * @ignore
+     * @param object $entity
+     * @return boolean
+     */
+    public function removeFromIdentityMap($entity)
+    {
+        $oid           = spl_object_hash($entity);
+        $classMetadata = $this->em->getClassMetadata(get_class($entity));
+        $idHash        = implode(' ', $this->entityIdentifiers[$oid]);
+
+        if ($idHash === '') {
+            throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "remove from identity map");
+        }
+
+        $className = $classMetadata->rootEntityName;
+
+        if (isset($this->identityMap[$className][$idHash])) {
+            unset($this->identityMap[$className][$idHash]);
+            unset($this->readOnlyObjects[$oid]);
+
+            //$this->entityStates[$oid] = self::STATE_DETACHED;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * INTERNAL:
+     * Gets an entity in the identity map by its identifier hash.
+     *
+     * @ignore
+     * @param string $idHash
+     * @param string $rootClassName
+     * @return object
+     */
+    public function getByIdHash($idHash, $rootClassName)
+    {
+        return $this->identityMap[$rootClassName][$idHash];
+    }
+
+    /**
+     * INTERNAL:
+     * Tries to get an entity by its identifier hash. If no entity is found for
+     * the given hash, FALSE is returned.
+     *
+     * @ignore
+     * @param string $idHash
+     * @param string $rootClassName
+     * @return mixed The found entity or FALSE.
+     */
+    public function tryGetByIdHash($idHash, $rootClassName)
+    {
+        if (isset($this->identityMap[$rootClassName][$idHash])) {
+            return $this->identityMap[$rootClassName][$idHash];
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks whether an entity is registered in the identity map of this UnitOfWork.
+     *
+     * @param object $entity
+     * @return boolean
+     */
+    public function isInIdentityMap($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if ( ! isset($this->entityIdentifiers[$oid])) {
+            return false;
+        }
+
+        $classMetadata = $this->em->getClassMetadata(get_class($entity));
+        $idHash        = implode(' ', $this->entityIdentifiers[$oid]);
+
+        if ($idHash === '') {
+            return false;
+        }
+
+        return isset($this->identityMap[$classMetadata->rootEntityName][$idHash]);
+    }
+
+    /**
+     * INTERNAL:
+     * Checks whether an identifier hash exists in the identity map.
+     *
+     * @ignore
+     * @param string $idHash
+     * @param string $rootClassName
+     * @return boolean
+     */
+    public function containsIdHash($idHash, $rootClassName)
+    {
+        return isset($this->identityMap[$rootClassName][$idHash]);
+    }
+
+    /**
+     * Persists an entity as part of the current unit of work.
+     *
+     * @param object $entity The entity to persist.
+     */
+    public function persist($entity)
+    {
+        $visited = array();
+
+        $this->doPersist($entity, $visited);
+    }
+
+    /**
+     * Persists an entity as part of the current unit of work.
+     *
+     * This method is internally called during persist() cascades as it tracks
+     * the already visited entities to prevent infinite recursions.
+     *
+     * @param object $entity The entity to persist.
+     * @param array $visited The already visited entities.
+     */
+    private function doPersist($entity, array &$visited)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($visited[$oid])) {
+            return; // Prevent infinite recursion
+        }
+
+        $visited[$oid] = $entity; // Mark visited
+
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        // We assume NEW, so DETACHED entities result in an exception on flush (constraint violation).
+        // If we would detect DETACHED here we would throw an exception anyway with the same
+        // consequences (not recoverable/programming error), so just assuming NEW here
+        // lets us avoid some database lookups for entities with natural identifiers.
+        $entityState = $this->getEntityState($entity, self::STATE_NEW);
+
+        switch ($entityState) {
+            case self::STATE_MANAGED:
+                // Nothing to do, except if policy is "deferred explicit"
+                if ($class->isChangeTrackingDeferredExplicit()) {
+                    $this->scheduleForDirtyCheck($entity);
+                }
+                break;
+
+            case self::STATE_NEW:
+                $this->persistNew($class, $entity);
+                break;
+
+            case self::STATE_REMOVED:
+                // Entity becomes managed again
+                unset($this->entityDeletions[$oid]);
+
+                $this->entityStates[$oid] = self::STATE_MANAGED;
+                break;
+
+            case self::STATE_DETACHED:
+                // Can actually not happen right now since we assume STATE_NEW.
+                throw ORMInvalidArgumentException::detachedEntityCannot($entity, "persisted");
+
+            default:
+                throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity));
+        }
+
+        $this->cascadePersist($entity, $visited);
+    }
+
+    /**
+     * Deletes an entity as part of the current unit of work.
+     *
+     * @param object $entity The entity to remove.
+     */
+    public function remove($entity)
+    {
+        $visited = array();
+
+        $this->doRemove($entity, $visited);
+    }
+
+    /**
+     * Deletes an entity as part of the current unit of work.
+     *
+     * This method is internally called during delete() cascades as it tracks
+     * the already visited entities to prevent infinite recursions.
+     *
+     * @param object $entity The entity to delete.
+     * @param array $visited The map of the already visited entities.
+     * @throws InvalidArgumentException If the instance is a detached entity.
+     */
+    private function doRemove($entity, array &$visited)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($visited[$oid])) {
+            return; // Prevent infinite recursion
+        }
+
+        $visited[$oid] = $entity; // mark visited
+
+        // Cascade first, because scheduleForDelete() removes the entity from the identity map, which
+        // can cause problems when a lazy proxy has to be initialized for the cascade operation.
+        $this->cascadeRemove($entity, $visited);
+
+        $class       = $this->em->getClassMetadata(get_class($entity));
+        $entityState = $this->getEntityState($entity);
+
+        switch ($entityState) {
+            case self::STATE_NEW:
+            case self::STATE_REMOVED:
+                // nothing to do
+                break;
+
+            case self::STATE_MANAGED:
+                if (isset($class->lifecycleCallbacks[Events::preRemove])) {
+                    $class->invokeLifecycleCallbacks(Events::preRemove, $entity);
+                }
+
+                if ($this->evm->hasListeners(Events::preRemove)) {
+                    $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity, $this->em));
+                }
+
+                $this->scheduleForDelete($entity);
+                break;
+
+            case self::STATE_DETACHED:
+                throw ORMInvalidArgumentException::detachedEntityCannot($entity, "removed");
+            default:
+                throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity));
+        }
+
+    }
+
+    /**
+     * Merges the state of the given detached entity into this UnitOfWork.
+     *
+     * @param object $entity
+     * @return object The managed copy of the entity.
+     * @throws OptimisticLockException If the entity uses optimistic locking through a version
+     *         attribute and the version check against the managed copy fails.
+     *
+     * @todo Require active transaction!? OptimisticLockException may result in undefined state!?
+     */
+    public function merge($entity)
+    {
+        $visited = array();
+
+        return $this->doMerge($entity, $visited);
+    }
+
+    /**
+     * Executes a merge operation on an entity.
+     *
+     * @param object $entity
+     * @param array $visited
+     * @return object The managed copy of the entity.
+     * @throws OptimisticLockException If the entity uses optimistic locking through a version
+     *         attribute and the version check against the managed copy fails.
+     * @throws InvalidArgumentException If the entity instance is NEW.
+     */
+    private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($visited[$oid])) {
+            return $visited[$oid]; // Prevent infinite recursion
+        }
+
+        $visited[$oid] = $entity; // mark visited
+
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        // First we assume DETACHED, although it can still be NEW but we can avoid
+        // an extra db-roundtrip this way. If it is not MANAGED but has an identity,
+        // we need to fetch it from the db anyway in order to merge.
+        // MANAGED entities are ignored by the merge operation.
+        $managedCopy = $entity;
+
+        if ($this->getEntityState($entity, self::STATE_DETACHED) !== self::STATE_MANAGED) {
+            if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
+                $entity->__load();
+            }
+
+            // Try to look the entity up in the identity map.
+            $id = $class->getIdentifierValues($entity);
+
+            // If there is no ID, it is actually NEW.
+            if ( ! $id) {
+                $managedCopy = $this->newInstance($class);
+
+                $this->persistNew($class, $managedCopy);
+            } else {
+                $flatId = $id;
+                if ($class->containsForeignIdentifier) {
+                    // convert foreign identifiers into scalar foreign key
+                    // values to avoid object to string conversion failures.
+                    foreach ($id as $idField => $idValue) {
+                        if (isset($class->associationMappings[$idField])) {
+                            $targetClassMetadata = $this->em->getClassMetadata($class->associationMappings[$idField]['targetEntity']);
+                            $associatedId = $this->getEntityIdentifier($idValue);
+                            $flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]];
+                        }
+                    }
+                }
+
+                $managedCopy = $this->tryGetById($flatId, $class->rootEntityName);
+
+                if ($managedCopy) {
+                    // We have the entity in-memory already, just make sure its not removed.
+                    if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) {
+                        throw ORMInvalidArgumentException::entityIsRemoved($managedCopy, "merge");
+                    }
+                } else {
+                    // We need to fetch the managed copy in order to merge.
+                    $managedCopy = $this->em->find($class->name, $flatId);
+                }
+
+                if ($managedCopy === null) {
+                    // If the identifier is ASSIGNED, it is NEW, otherwise an error
+                    // since the managed entity was not found.
+                    if ( ! $class->isIdentifierNatural()) {
+                        throw new EntityNotFoundException;
+                    }
+
+                    $managedCopy = $this->newInstance($class);
+                    $class->setIdentifierValues($managedCopy, $id);
+
+                    $this->persistNew($class, $managedCopy);
+                } else {
+                    if ($managedCopy instanceof Proxy && ! $managedCopy->__isInitialized__) {
+                        $managedCopy->__load();
+                    }
+                }
+            }
+
+            if ($class->isVersioned) {
+                $managedCopyVersion = $class->reflFields[$class->versionField]->getValue($managedCopy);
+                $entityVersion = $class->reflFields[$class->versionField]->getValue($entity);
+
+                // Throw exception if versions dont match.
+                if ($managedCopyVersion != $entityVersion) {
+                    throw OptimisticLockException::lockFailedVersionMissmatch($entity, $entityVersion, $managedCopyVersion);
+                }
+            }
+
+            // Merge state of $entity into existing (managed) entity
+            foreach ($class->reflFields as $name => $prop) {
+                if ( ! isset($class->associationMappings[$name])) {
+                    if ( ! $class->isIdentifier($name)) {
+                        $prop->setValue($managedCopy, $prop->getValue($entity));
+                    }
+                } else {
+                    $assoc2 = $class->associationMappings[$name];
+                    if ($assoc2['type'] & ClassMetadata::TO_ONE) {
+                        $other = $prop->getValue($entity);
+                        if ($other === null) {
+                            $prop->setValue($managedCopy, null);
+                        } else if ($other instanceof Proxy && !$other->__isInitialized__) {
+                            // do not merge fields marked lazy that have not been fetched.
+                            continue;
+                        } else if ( ! $assoc2['isCascadeMerge']) {
+                            if ($this->getEntityState($other, self::STATE_DETACHED) !== self::STATE_MANAGED) {
+                                $targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
+                                $relatedId = $targetClass->getIdentifierValues($other);
+
+                                if ($targetClass->subClasses) {
+                                    $other = $this->em->find($targetClass->name, $relatedId);
+                                } else {
+                                    $other = $this->em->getProxyFactory()->getProxy($assoc2['targetEntity'], $relatedId);
+                                    $this->registerManaged($other, $relatedId, array());
+                                }
+                            }
+                            $prop->setValue($managedCopy, $other);
+                        }
+                    } else {
+                        $mergeCol = $prop->getValue($entity);
+                        if ($mergeCol instanceof PersistentCollection && !$mergeCol->isInitialized()) {
+                            // do not merge fields marked lazy that have not been fetched.
+                            // keep the lazy persistent collection of the managed copy.
+                            continue;
+                        }
+
+                        $managedCol = $prop->getValue($managedCopy);
+                        if (!$managedCol) {
+                            $managedCol = new PersistentCollection($this->em,
+                                    $this->em->getClassMetadata($assoc2['targetEntity']),
+                                    new ArrayCollection
+                                    );
+                            $managedCol->setOwner($managedCopy, $assoc2);
+                            $prop->setValue($managedCopy, $managedCol);
+                            $this->originalEntityData[$oid][$name] = $managedCol;
+                        }
+                        if ($assoc2['isCascadeMerge']) {
+                            $managedCol->initialize();
+
+                            // clear and set dirty a managed collection if its not also the same collection to merge from.
+                            if (!$managedCol->isEmpty() && $managedCol !== $mergeCol) {
+                                $managedCol->unwrap()->clear();
+                                $managedCol->setDirty(true);
+
+                                if ($assoc2['isOwningSide'] && $assoc2['type'] == ClassMetadata::MANY_TO_MANY && $class->isChangeTrackingNotify()) {
+                                    $this->scheduleForDirtyCheck($managedCopy);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if ($class->isChangeTrackingNotify()) {
+                    // Just treat all properties as changed, there is no other choice.
+                    $this->propertyChanged($managedCopy, $name, null, $prop->getValue($managedCopy));
+                }
+            }
+
+            if ($class->isChangeTrackingDeferredExplicit()) {
+                $this->scheduleForDirtyCheck($entity);
+            }
+        }
+
+        if ($prevManagedCopy !== null) {
+            $assocField = $assoc['fieldName'];
+            $prevClass = $this->em->getClassMetadata(get_class($prevManagedCopy));
+
+            if ($assoc['type'] & ClassMetadata::TO_ONE) {
+                $prevClass->reflFields[$assocField]->setValue($prevManagedCopy, $managedCopy);
+            } else {
+                $prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->add($managedCopy);
+
+                if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) {
+                    $class->reflFields[$assoc['mappedBy']]->setValue($managedCopy, $prevManagedCopy);
+                }
+            }
+        }
+
+        // Mark the managed copy visited as well
+        $visited[spl_object_hash($managedCopy)] = true;
+
+        $this->cascadeMerge($entity, $managedCopy, $visited);
+
+        return $managedCopy;
+    }
+
+    /**
+     * Detaches an entity from the persistence management. It's persistence will
+     * no longer be managed by Doctrine.
+     *
+     * @param object $entity The entity to detach.
+     */
+    public function detach($entity)
+    {
+        $visited = array();
+
+        $this->doDetach($entity, $visited);
+    }
+
+    /**
+     * Executes a detach operation on the given entity.
+     *
+     * @param object $entity
+     * @param array $visited
+     * @param boolean $noCascade if true, don't cascade detach operation
+     */
+    private function doDetach($entity, array &$visited, $noCascade = false)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($visited[$oid])) {
+            return; // Prevent infinite recursion
+        }
+
+        $visited[$oid] = $entity; // mark visited
+
+        switch ($this->getEntityState($entity, self::STATE_DETACHED)) {
+            case self::STATE_MANAGED:
+                if ($this->isInIdentityMap($entity)) {
+                    $this->removeFromIdentityMap($entity);
+                }
+
+                unset(
+                    $this->entityInsertions[$oid],
+                    $this->entityUpdates[$oid],
+                    $this->entityDeletions[$oid],
+                    $this->entityIdentifiers[$oid],
+                    $this->entityStates[$oid],
+                    $this->originalEntityData[$oid]
+                );
+                break;
+            case self::STATE_NEW:
+            case self::STATE_DETACHED:
+                return;
+        }
+
+        if ( ! $noCascade) {
+            $this->cascadeDetach($entity, $visited);
+        }
+    }
+
+    /**
+     * Refreshes the state of the given entity from the database, overwriting
+     * any local, unpersisted changes.
+     *
+     * @param object $entity The entity to refresh.
+     * @throws InvalidArgumentException If the entity is not MANAGED.
+     */
+    public function refresh($entity)
+    {
+        $visited = array();
+
+        $this->doRefresh($entity, $visited);
+    }
+
+    /**
+     * Executes a refresh operation on an entity.
+     *
+     * @param object $entity The entity to refresh.
+     * @param array $visited The already visited entities during cascades.
+     * @throws InvalidArgumentException If the entity is not MANAGED.
+     */
+    private function doRefresh($entity, array &$visited)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($visited[$oid])) {
+            return; // Prevent infinite recursion
+        }
+
+        $visited[$oid] = $entity; // mark visited
+
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        if ($this->getEntityState($entity) !== self::STATE_MANAGED) {
+            throw ORMInvalidArgumentException::entityNotManaged($entity);
+        }
+
+        $this->getEntityPersister($class->name)->refresh(
+            array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]),
+            $entity
+        );
+
+        $this->cascadeRefresh($entity, $visited);
+    }
+
+    /**
+     * Cascades a refresh operation to associated entities.
+     *
+     * @param object $entity
+     * @param array $visited
+     */
+    private function cascadeRefresh($entity, array &$visited)
+    {
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $associationMappings = array_filter(
+            $class->associationMappings,
+            function ($assoc) { return $assoc['isCascadeRefresh']; }
+        );
+
+        foreach ($associationMappings as $assoc) {
+            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);
+
+            switch (true) {
+                case ($relatedEntities instanceof PersistentCollection):
+                    // Unwrap so that foreach() does not initialize
+                    $relatedEntities = $relatedEntities->unwrap();
+                    // break; is commented intentionally!
+
+                case ($relatedEntities instanceof Collection):
+                case (is_array($relatedEntities)):
+                    foreach ($relatedEntities as $relatedEntity) {
+                        $this->doRefresh($relatedEntity, $visited);
+                    }
+                    break;
+
+                case ($relatedEntities !== null):
+                    $this->doRefresh($relatedEntities, $visited);
+                    break;
+
+                default:
+                    // Do nothing
+            }
+        }
+    }
+
+    /**
+     * Cascades a detach operation to associated entities.
+     *
+     * @param object $entity
+     * @param array $visited
+     */
+    private function cascadeDetach($entity, array &$visited)
+    {
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $associationMappings = array_filter(
+            $class->associationMappings,
+            function ($assoc) { return $assoc['isCascadeDetach']; }
+        );
+
+        foreach ($associationMappings as $assoc) {
+            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);
+
+            switch (true) {
+                case ($relatedEntities instanceof PersistentCollection):
+                    // Unwrap so that foreach() does not initialize
+                    $relatedEntities = $relatedEntities->unwrap();
+                    // break; is commented intentionally!
+
+                case ($relatedEntities instanceof Collection):
+                case (is_array($relatedEntities)):
+                    foreach ($relatedEntities as $relatedEntity) {
+                        $this->doDetach($relatedEntity, $visited);
+                    }
+                    break;
+
+                case ($relatedEntities !== null):
+                    $this->doDetach($relatedEntities, $visited);
+                    break;
+
+                default:
+                    // Do nothing
+            }
+        }
+    }
+
+    /**
+     * Cascades a merge operation to associated entities.
+     *
+     * @param object $entity
+     * @param object $managedCopy
+     * @param array $visited
+     */
+    private function cascadeMerge($entity, $managedCopy, array &$visited)
+    {
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $associationMappings = array_filter(
+            $class->associationMappings,
+            function ($assoc) { return $assoc['isCascadeMerge']; }
+        );
+
+        foreach ($associationMappings as $assoc) {
+            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);
+
+            if ($relatedEntities instanceof Collection) {
+                if ($relatedEntities === $class->reflFields[$assoc['fieldName']]->getValue($managedCopy)) {
+                    continue;
+                }
+
+                if ($relatedEntities instanceof PersistentCollection) {
+                    // Unwrap so that foreach() does not initialize
+                    $relatedEntities = $relatedEntities->unwrap();
+                }
+
+                foreach ($relatedEntities as $relatedEntity) {
+                    $this->doMerge($relatedEntity, $visited, $managedCopy, $assoc);
+                }
+            } else if ($relatedEntities !== null) {
+                $this->doMerge($relatedEntities, $visited, $managedCopy, $assoc);
+            }
+        }
+    }
+
+    /**
+     * Cascades the save operation to associated entities.
+     *
+     * @param object $entity
+     * @param array $visited
+     * @param array $insertNow
+     */
+    private function cascadePersist($entity, array &$visited)
+    {
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $associationMappings = array_filter(
+            $class->associationMappings,
+            function ($assoc) { return $assoc['isCascadePersist']; }
+        );
+
+        foreach ($associationMappings as $assoc) {
+            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);
+
+            switch (true) {
+                case ($relatedEntities instanceof PersistentCollection):
+                    // Unwrap so that foreach() does not initialize
+                    $relatedEntities = $relatedEntities->unwrap();
+                    // break; is commented intentionally!
+
+                case ($relatedEntities instanceof Collection):
+                case (is_array($relatedEntities)):
+                    foreach ($relatedEntities as $relatedEntity) {
+                        $this->doPersist($relatedEntity, $visited);
+                    }
+                    break;
+
+                case ($relatedEntities !== null):
+                    $this->doPersist($relatedEntities, $visited);
+                    break;
+
+                default:
+                    // Do nothing
+            }
+        }
+    }
+
+    /**
+     * Cascades the delete operation to associated entities.
+     *
+     * @param object $entity
+     * @param array $visited
+     */
+    private function cascadeRemove($entity, array &$visited)
+    {
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $associationMappings = array_filter(
+            $class->associationMappings,
+            function ($assoc) { return $assoc['isCascadeRemove']; }
+        );
+
+        foreach ($associationMappings as $assoc) {
+            if ($entity instanceof Proxy && !$entity->__isInitialized__) {
+                $entity->__load();
+            }
+
+            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);
+
+            switch (true) {
+                case ($relatedEntities instanceof Collection):
+                case (is_array($relatedEntities)):
+                    // If its a PersistentCollection initialization is intended! No unwrap!
+                    foreach ($relatedEntities as $relatedEntity) {
+                        $this->doRemove($relatedEntity, $visited);
+                    }
+                    break;
+
+                case ($relatedEntities !== null):
+                    $this->doRemove($relatedEntities, $visited);
+                    break;
+
+                default:
+                    // Do nothing
+            }
+        }
+    }
+
+    /**
+     * Acquire a lock on the given entity.
+     *
+     * @param object $entity
+     * @param int $lockMode
+     * @param int $lockVersion
+     */
+    public function lock($entity, $lockMode, $lockVersion = null)
+    {
+        if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) {
+            throw ORMInvalidArgumentException::entityNotManaged($entity);
+        }
+
+        $entityName = get_class($entity);
+        $class = $this->em->getClassMetadata($entityName);
+
+        switch ($lockMode) {
+            case \Doctrine\DBAL\LockMode::OPTIMISTIC;
+                if ( ! $class->isVersioned) {
+                    throw OptimisticLockException::notVersioned($entityName);
+                }
+
+                if ($lockVersion === null) {
+                    return;
+                }
+
+                $entityVersion = $class->reflFields[$class->versionField]->getValue($entity);
+
+                if ($entityVersion != $lockVersion) {
+                    throw OptimisticLockException::lockFailedVersionMissmatch($entity, $lockVersion, $entityVersion);
+                }
+
+                break;
+
+            case \Doctrine\DBAL\LockMode::PESSIMISTIC_READ:
+            case \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE:
+                if (!$this->em->getConnection()->isTransactionActive()) {
+                    throw TransactionRequiredException::transactionRequired();
+                }
+
+                $oid = spl_object_hash($entity);
+
+                $this->getEntityPersister($class->name)->lock(
+                    array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]),
+                    $lockMode
+                );
+                break;
+
+            default:
+                // Do nothing
+        }
+    }
+
+    /**
+     * Gets the CommitOrderCalculator used by the UnitOfWork to order commits.
+     *
+     * @return \Doctrine\ORM\Internal\CommitOrderCalculator
+     */
+    public function getCommitOrderCalculator()
+    {
+        if ($this->commitOrderCalculator === null) {
+            $this->commitOrderCalculator = new Internal\CommitOrderCalculator;
+        }
+
+        return $this->commitOrderCalculator;
+    }
+
+    /**
+     * Clears the UnitOfWork.
+     *
+     * @param string $entityName if given, only entities of this type will get detached
+     */
+    public function clear($entityName = null)
+    {
+        if ($entityName === null) {
+            $this->identityMap =
+            $this->entityIdentifiers =
+            $this->originalEntityData =
+            $this->entityChangeSets =
+            $this->entityStates =
+            $this->scheduledForDirtyCheck =
+            $this->entityInsertions =
+            $this->entityUpdates =
+            $this->entityDeletions =
+            $this->collectionDeletions =
+            $this->collectionUpdates =
+            $this->extraUpdates =
+            $this->readOnlyObjects =
+            $this->orphanRemovals = array();
+
+            if ($this->commitOrderCalculator !== null) {
+                $this->commitOrderCalculator->clear();
+            }
+        } else {
+            $visited = array();
+            foreach ($this->identityMap as $className => $entities) {
+                if ($className === $entityName) {
+                    foreach ($entities as $entity) {
+                        $this->doDetach($entity, $visited, true);
+                    }
+                }
+            }
+        }
+
+        if ($this->evm->hasListeners(Events::onClear)) {
+            $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em, $entityName));
+        }
+    }
+
+    /**
+     * INTERNAL:
+     * Schedules an orphaned entity for removal. The remove() operation will be
+     * invoked on that entity at the beginning of the next commit of this
+     * UnitOfWork.
+     *
+     * @ignore
+     * @param object $entity
+     */
+    public function scheduleOrphanRemoval($entity)
+    {
+        $this->orphanRemovals[spl_object_hash($entity)] = $entity;
+    }
+
+    /**
+     * INTERNAL:
+     * Schedules a complete collection for removal when this UnitOfWork commits.
+     *
+     * @param PersistentCollection $coll
+     */
+    public function scheduleCollectionDeletion(PersistentCollection $coll)
+    {
+        $coid = spl_object_hash($coll);
+
+        //TODO: if $coll is already scheduled for recreation ... what to do?
+        // Just remove $coll from the scheduled recreations?
+        if (isset($this->collectionUpdates[$coid])) {
+            unset($this->collectionUpdates[$coid]);
+        }
+
+        $this->collectionDeletions[$coid] = $coll;
+    }
+
+    public function isCollectionScheduledForDeletion(PersistentCollection $coll)
+    {
+        return isset($this->collectionsDeletions[spl_object_hash($coll)]);
+    }
+
+    /**
+     * @param ClassMetadata $class
+     */
+    private function newInstance($class)
+    {
+        $entity = $class->newInstance();
+
+        if ($entity instanceof \Doctrine\Common\Persistence\ObjectManagerAware) {
+            $entity->injectObjectManager($this->em, $class);
+        }
+
+        return $entity;
+    }
+
+    /**
+     * INTERNAL:
+     * Creates an entity. Used for reconstitution of persistent entities.
+     *
+     * @ignore
+     * @param string $className The name of the entity class.
+     * @param array $data The data for the entity.
+     * @param array $hints Any hints to account for during reconstitution/lookup of the entity.
+     * @return object The managed entity instance.
+     * @internal Highly performance-sensitive method.
+     *
+     * @todo Rename: getOrCreateEntity
+     */
+    public function createEntity($className, array $data, &$hints = array())
+    {
+        $class = $this->em->getClassMetadata($className);
+        //$isReadOnly = isset($hints[Query::HINT_READ_ONLY]);
+
+        if ($class->isIdentifierComposite) {
+            $id = array();
+
+            foreach ($class->identifier as $fieldName) {
+                $id[$fieldName] = isset($class->associationMappings[$fieldName])
+                    ? $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']]
+                    : $data[$fieldName];
+            }
+
+            $idHash = implode(' ', $id);
+        } else {
+            $idHash = isset($class->associationMappings[$class->identifier[0]])
+                ? $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]
+                : $data[$class->identifier[0]];
+
+            $id = array($class->identifier[0] => $idHash);
+        }
+
+        if (isset($this->identityMap[$class->rootEntityName][$idHash])) {
+            $entity = $this->identityMap[$class->rootEntityName][$idHash];
+            $oid = spl_object_hash($entity);
+
+            if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
+                $entity->__isInitialized__ = true;
+                $overrideLocalValues = true;
+
+                if ($entity instanceof NotifyPropertyChanged) {
+                    $entity->addPropertyChangedListener($this);
+                }
+            } else {
+                $overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
+
+                // If only a specific entity is set to refresh, check that it's the one
+                if(isset($hints[Query::HINT_REFRESH_ENTITY])) {
+                    $overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity;
+
+                    // inject ObjectManager into just loaded proxies.
+                    if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
+                        $entity->injectObjectManager($this->em, $class);
+                    }
+                }
+            }
+
+            if ($overrideLocalValues) {
+                $this->originalEntityData[$oid] = $data;
+            }
+        } else {
+            $entity = $this->newInstance($class);
+            $oid    = spl_object_hash($entity);
+
+            $this->entityIdentifiers[$oid]  = $id;
+            $this->entityStates[$oid]       = self::STATE_MANAGED;
+            $this->originalEntityData[$oid] = $data;
+
+            $this->identityMap[$class->rootEntityName][$idHash] = $entity;
+
+            if ($entity instanceof NotifyPropertyChanged) {
+                $entity->addPropertyChangedListener($this);
+            }
+
+            $overrideLocalValues = true;
+        }
+
+        if ( ! $overrideLocalValues) {
+            return $entity;
+        }
+
+        foreach ($data as $field => $value) {
+            if (isset($class->fieldMappings[$field])) {
+                $class->reflFields[$field]->setValue($entity, $value);
+            }
+        }
+
+        // Loading the entity right here, if its in the eager loading map get rid of it there.
+        unset($this->eagerLoadingEntities[$class->rootEntityName][$idHash]);
+
+        if (isset($this->eagerLoadingEntities[$class->rootEntityName]) && ! $this->eagerLoadingEntities[$class->rootEntityName]) {
+            unset($this->eagerLoadingEntities[$class->rootEntityName]);
+        }
+
+        // Properly initialize any unfetched associations, if partial objects are not allowed.
+        if (isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) {
+            return $entity;
+        }
+
+        foreach ($class->associationMappings as $field => $assoc) {
+            // Check if the association is not among the fetch-joined associations already.
+            if (isset($hints['fetchAlias']) && isset($hints['fetched'][$hints['fetchAlias']][$field])) {
+                continue;
+            }
+
+            $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
+
+            switch (true) {
+                case ($assoc['type'] & ClassMetadata::TO_ONE):
+                    if ( ! $assoc['isOwningSide']) {
+                        // Inverse side of x-to-one can never be lazy
+                        $class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity));
+
+                        continue 2;
+                    }
+
+                    $associatedId = array();
+
+                    // TODO: Is this even computed right in all cases of composite keys?
+                    foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
+                        $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
+
+                        if ($joinColumnValue !== null) {
+                            if ($targetClass->containsForeignIdentifier) {
+                                $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue;
+                            } else {
+                                $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
+                            }
+                        }
+                    }
+
+                    if ( ! $associatedId) {
+                        // Foreign key is NULL
+                        $class->reflFields[$field]->setValue($entity, null);
+                        $this->originalEntityData[$oid][$field] = null;
+
+                        continue;
+                    }
+
+                    if ( ! isset($hints['fetchMode'][$class->name][$field])) {
+                        $hints['fetchMode'][$class->name][$field] = $assoc['fetch'];
+                    }
+
+                    // Foreign key is set
+                    // Check identity map first
+                    // FIXME: Can break easily with composite keys if join column values are in
+                    //        wrong order. The correct order is the one in ClassMetadata#identifier.
+                    $relatedIdHash = implode(' ', $associatedId);
+
+                    switch (true) {
+                        case (isset($this->identityMap[$targetClass->rootEntityName][$relatedIdHash])):
+                            $newValue = $this->identityMap[$targetClass->rootEntityName][$relatedIdHash];
+
+                            // if this is an uninitialized proxy, we are deferring eager loads,
+                            // this association is marked as eager fetch, and its an uninitialized proxy (wtf!)
+                            // then we cann append this entity for eager loading!
+                            if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER &&
+                                isset($hints['deferEagerLoad']) &&
+                                !$targetClass->isIdentifierComposite &&
+                                $newValue instanceof Proxy &&
+                                $newValue->__isInitialized__ === false) {
+
+                                $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
+                            }
+
+                            break;
+
+                        case ($targetClass->subClasses):
+                            // If it might be a subtype, it can not be lazy. There isn't even
+                            // a way to solve this with deferred eager loading, which means putting
+                            // an entity with subclasses at a *-to-one location is really bad! (performance-wise)
+                            $newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, $associatedId);
+                            break;
+
+                        default:
+                            switch (true) {
+                                // We are negating the condition here. Other cases will assume it is valid!
+                                case ($hints['fetchMode'][$class->name][$field] !== ClassMetadata::FETCH_EAGER):
+                                    $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
+                                    break;
+
+                                // Deferred eager load only works for single identifier classes
+                                case (isset($hints['deferEagerLoad']) && ! $targetClass->isIdentifierComposite):
+                                    // TODO: Is there a faster approach?
+                                    $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
+
+                                    $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
+                                    break;
+
+                                default:
+                                    // TODO: This is very imperformant, ignore it?
+                                    $newValue = $this->em->find($assoc['targetEntity'], $associatedId);
+                                    break;
+                            }
+
+                            // PERF: Inlined & optimized code from UnitOfWork#registerManaged()
+                            $newValueOid = spl_object_hash($newValue);
+                            $this->entityIdentifiers[$newValueOid] = $associatedId;
+                            $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
+                            $this->entityStates[$newValueOid] = self::STATE_MANAGED;
+                            // make sure that when an proxy is then finally loaded, $this->originalEntityData is set also!
+                            break;
+                    }
+
+                    $this->originalEntityData[$oid][$field] = $newValue;
+                    $class->reflFields[$field]->setValue($entity, $newValue);
+
+                    if ($assoc['inversedBy'] && $assoc['type'] & ClassMetadata::ONE_TO_ONE) {
+                        $inverseAssoc = $targetClass->associationMappings[$assoc['inversedBy']];
+                        $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($newValue, $entity);
+                    }
+
+                    break;
+
+                default:
+                    // Inject collection
+                    $pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection);
+                    $pColl->setOwner($entity, $assoc);
+                    $pColl->setInitialized(false);
+
+                    $reflField = $class->reflFields[$field];
+                    $reflField->setValue($entity, $pColl);
+
+                    if ($assoc['fetch'] == ClassMetadata::FETCH_EAGER) {
+                        $this->loadCollection($pColl);
+                        $pColl->takeSnapshot();
+                    }
+
+                    $this->originalEntityData[$oid][$field] = $pColl;
+                    break;
+            }
+        }
+
+        if ($overrideLocalValues) {
+            if (isset($class->lifecycleCallbacks[Events::postLoad])) {
+                $class->invokeLifecycleCallbacks(Events::postLoad, $entity);
+            }
+
+
+            if ($this->evm->hasListeners(Events::postLoad)) {
+                $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em));
+            }
+        }
+
+        return $entity;
+    }
+
+    /**
+     * @return void
+     */
+    public function triggerEagerLoads()
+    {
+        if ( ! $this->eagerLoadingEntities) {
+            return;
+        }
+
+        // avoid infinite recursion
+        $eagerLoadingEntities       = $this->eagerLoadingEntities;
+        $this->eagerLoadingEntities = array();
+
+        foreach ($eagerLoadingEntities as $entityName => $ids) {
+            $class = $this->em->getClassMetadata($entityName);
+
+            if ($ids) {
+                $this->getEntityPersister($entityName)->loadAll(
+                    array_combine($class->identifier, array(array_values($ids)))
+                );
+            }
+        }
+    }
+
+    /**
+     * Initializes (loads) an uninitialized persistent collection of an entity.
+     *
+     * @param PeristentCollection $collection The collection to initialize.
+     * @todo Maybe later move to EntityManager#initialize($proxyOrCollection). See DDC-733.
+     */
+    public function loadCollection(PersistentCollection $collection)
+    {
+        $assoc     = $collection->getMapping();
+        $persister = $this->getEntityPersister($assoc['targetEntity']);
+
+        switch ($assoc['type']) {
+            case ClassMetadata::ONE_TO_MANY:
+                $persister->loadOneToManyCollection($assoc, $collection->getOwner(), $collection);
+                break;
+
+            case ClassMetadata::MANY_TO_MANY:
+                $persister->loadManyToManyCollection($assoc, $collection->getOwner(), $collection);
+                break;
+        }
+    }
+
+    /**
+     * Gets the identity map of the UnitOfWork.
+     *
+     * @return array
+     */
+    public function getIdentityMap()
+    {
+        return $this->identityMap;
+    }
+
+    /**
+     * Gets the original data of an entity. The original data is the data that was
+     * present at the time the entity was reconstituted from the database.
+     *
+     * @param object $entity
+     * @return array
+     */
+    public function getOriginalEntityData($entity)
+    {
+        $oid = spl_object_hash($entity);
+
+        if (isset($this->originalEntityData[$oid])) {
+            return $this->originalEntityData[$oid];
+        }
+
+        return array();
+    }
+
+    /**
+     * @ignore
+     */
+    public function setOriginalEntityData($entity, array $data)
+    {
+        $this->originalEntityData[spl_object_hash($entity)] = $data;
+    }
+
+    /**
+     * INTERNAL:
+     * Sets a property value of the original data array of an entity.
+     *
+     * @ignore
+     * @param string $oid
+     * @param string $property
+     * @param mixed $value
+     */
+    public function setOriginalEntityProperty($oid, $property, $value)
+    {
+        $this->originalEntityData[$oid][$property] = $value;
+    }
+
+    /**
+     * Gets the identifier of an entity.
+     * The returned value is always an array of identifier values. If the entity
+     * has a composite identifier then the identifier values are in the same
+     * order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
+     *
+     * @param object $entity
+     * @return array The identifier values.
+     */
+    public function getEntityIdentifier($entity)
+    {
+        return $this->entityIdentifiers[spl_object_hash($entity)];
+    }
+
+    /**
+     * Tries to find an entity with the given identifier in the identity map of
+     * this UnitOfWork.
+     *
+     * @param mixed $id The entity identifier to look for.
+     * @param string $rootClassName The name of the root class of the mapped entity hierarchy.
+     * @return mixed Returns the entity with the specified identifier if it exists in
+     *               this UnitOfWork, FALSE otherwise.
+     */
+    public function tryGetById($id, $rootClassName)
+    {
+        $idHash = implode(' ', (array) $id);
+
+        if (isset($this->identityMap[$rootClassName][$idHash])) {
+            return $this->identityMap[$rootClassName][$idHash];
+        }
+
+        return false;
+    }
+
+    /**
+     * Schedules an entity for dirty-checking at commit-time.
+     *
+     * @param object $entity The entity to schedule for dirty-checking.
+     * @todo Rename: scheduleForSynchronization
+     */
+    public function scheduleForDirtyCheck($entity)
+    {
+        $rootClassName = $this->em->getClassMetadata(get_class($entity))->rootEntityName;
+
+        $this->scheduledForDirtyCheck[$rootClassName][spl_object_hash($entity)] = $entity;
+    }
+
+    /**
+     * Checks whether the UnitOfWork has any pending insertions.
+     *
+     * @return boolean TRUE if this UnitOfWork has pending insertions, FALSE otherwise.
+     */
+    public function hasPendingInsertions()
+    {
+        return ! empty($this->entityInsertions);
+    }
+
+    /**
+     * Calculates the size of the UnitOfWork. The size of the UnitOfWork is the
+     * number of entities in the identity map.
+     *
+     * @return integer
+     */
+    public function size()
+    {
+        $countArray = array_map(function ($item) { return count($item); }, $this->identityMap);
+
+        return array_sum($countArray);
+    }
+
+    /**
+     * Gets the EntityPersister for an Entity.
+     *
+     * @param string $entityName  The name of the Entity.
+     *
+     * @return \Doctrine\ORM\Persisters\BasicEntityPersister
+     */
+    public function getEntityPersister($entityName)
+    {
+        if (isset($this->persisters[$entityName])) {
+            return $this->persisters[$entityName];
+        }
+
+        $class = $this->em->getClassMetadata($entityName);
+
+        switch (true) {
+            case ($class->isInheritanceTypeNone()):
+                $persister = new Persisters\BasicEntityPersister($this->em, $class);
+                break;
+
+            case ($class->isInheritanceTypeSingleTable()):
+                $persister = new Persisters\SingleTablePersister($this->em, $class);
+                break;
+
+            case ($class->isInheritanceTypeJoined()):
+                $persister = new Persisters\JoinedSubclassPersister($this->em, $class);
+                break;
+
+            default:
+                $persister = new Persisters\UnionSubclassPersister($this->em, $class);
+        }
+
+        $this->persisters[$entityName] = $persister;
+
+        return $this->persisters[$entityName];
+    }
+
+    /**
+     * Gets a collection persister for a collection-valued association.
+     *
+     * @param AssociationMapping $association
+     *
+     * @return AbstractCollectionPersister
+     */
+    public function getCollectionPersister(array $association)
+    {
+        $type = $association['type'];
+
+        if (isset($this->collectionPersisters[$type])) {
+            return $this->collectionPersisters[$type];
+        }
+
+        switch ($type) {
+            case ClassMetadata::ONE_TO_MANY:
+                $persister = new Persisters\OneToManyPersister($this->em);
+                break;
+
+            case ClassMetadata::MANY_TO_MANY:
+                $persister = new Persisters\ManyToManyPersister($this->em);
+                break;
+        }
+
+        $this->collectionPersisters[$type] = $persister;
+
+        return $this->collectionPersisters[$type];
+    }
+
+    /**
+     * INTERNAL:
+     * Registers an entity as managed.
+     *
+     * @param object $entity The entity.
+     * @param array $id The identifier values.
+     * @param array $data The original entity data.
+     */
+    public function registerManaged($entity, array $id, array $data)
+    {
+        $oid = spl_object_hash($entity);
+
+        $this->entityIdentifiers[$oid]  = $id;
+        $this->entityStates[$oid]       = self::STATE_MANAGED;
+        $this->originalEntityData[$oid] = $data;
+
+        $this->addToIdentityMap($entity);
+
+        if ($entity instanceof NotifyPropertyChanged) {
+            $entity->addPropertyChangedListener($this);
+        }
+    }
+
+    /**
+     * INTERNAL:
+     * Clears the property changeset of the entity with the given OID.
+     *
+     * @param string $oid The entity's OID.
+     */
+    public function clearEntityChangeSet($oid)
+    {
+        $this->entityChangeSets[$oid] = array();
+    }
+
+    /* PropertyChangedListener implementation */
+
+    /**
+     * Notifies this UnitOfWork of a property change in an entity.
+     *
+     * @param object $entity The entity that owns the property.
+     * @param string $propertyName The name of the property that changed.
+     * @param mixed $oldValue The old value of the property.
+     * @param mixed $newValue The new value of the property.
+     */
+    public function propertyChanged($entity, $propertyName, $oldValue, $newValue)
+    {
+        $oid   = spl_object_hash($entity);
+        $class = $this->em->getClassMetadata(get_class($entity));
+
+        $isAssocField = isset($class->associationMappings[$propertyName]);
+
+        if ( ! $isAssocField && ! isset($class->fieldMappings[$propertyName])) {
+            return; // ignore non-persistent fields
+        }
+
+        // Update changeset and mark entity for synchronization
+        $this->entityChangeSets[$oid][$propertyName] = array($oldValue, $newValue);
+
+        if ( ! isset($this->scheduledForDirtyCheck[$class->rootEntityName][$oid])) {
+            $this->scheduleForDirtyCheck($entity);
+        }
+    }
+
+    /**
+     * Gets the currently scheduled entity insertions in this UnitOfWork.
+     *
+     * @return array
+     */
+    public function getScheduledEntityInsertions()
+    {
+        return $this->entityInsertions;
+    }
+
+    /**
+     * Gets the currently scheduled entity updates in this UnitOfWork.
+     *
+     * @return array
+     */
+    public function getScheduledEntityUpdates()
+    {
+        return $this->entityUpdates;
+    }
+
+    /**
+     * Gets the currently scheduled entity deletions in this UnitOfWork.
+     *
+     * @return array
+     */
+    public function getScheduledEntityDeletions()
+    {
+        return $this->entityDeletions;
+    }
+
+    /**
+     * Get the currently scheduled complete collection deletions
+     *
+     * @return array
+     */
+    public function getScheduledCollectionDeletions()
+    {
+        return $this->collectionDeletions;
+    }
+
+    /**
+     * Gets the currently scheduled collection inserts, updates and deletes.
+     *
+     * @return array
+     */
+    public function getScheduledCollectionUpdates()
+    {
+        return $this->collectionUpdates;
+    }
+
+    /**
+     * Helper method to initialize a lazy loading proxy or persistent collection.
+     *
+     * @param object
+     * @return void
+     */
+    public function initializeObject($obj)
+    {
+        if ($obj instanceof Proxy) {
+            $obj->__load();
+
+            return;
+        }
+
+        if ($obj instanceof PersistentCollection) {
+            $obj->initialize();
+        }
+    }
+
+    /**
+     * Helper method to show an object as string.
+     *
+     * @param  object $obj
+     * @return string
+     */
+    private static function objToStr($obj)
+    {
+        return method_exists($obj, '__toString') ? (string)$obj : get_class($obj).'@'.spl_object_hash($obj);
+    }
+
+    /**
+     * Marks an entity as read-only so that it will not be considered for updates during UnitOfWork#commit().
+     *
+     * This operation cannot be undone as some parts of the UnitOfWork now keep gathering information
+     * on this object that might be necessary to perform a correct udpate.
+     *
+     * @throws \InvalidArgumentException
+     * @param $object
+     * @return void
+     */
+    public function markReadOnly($object)
+    {
+        if ( ! is_object($object) || ! $this->isInIdentityMap($object)) {
+            throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object);
+        }
+
+        $this->readOnlyObjects[spl_object_hash($object)] = true;
+    }
+
+    /**
+     * Is this entity read only?
+     *
+     * @throws \InvalidArgumentException
+     * @param $object
+     * @return void
+     */
+    public function isReadOnly($object)
+    {
+        if ( ! is_object($object) ) {
+            throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object);
+        }
+
+        return isset($this->readOnlyObjects[spl_object_hash($object)]);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Version.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Version.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Version.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM;
+
+/**
+ * Class to store and retrieve the version of Doctrine
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Version
+{
+    /**
+     * Current Doctrine Version
+     */
+    const VERSION = '2.2.3';
+
+    /**
+     * Compares a Doctrine version with the current one.
+     *
+     * @param string $version Doctrine version to compare.
+     * @return int Returns -1 if older, 0 if it is the same, 1 if version
+     *             passed as argument is newer.
+     */
+    public static function compare($version)
+    {
+        $currentVersion = str_replace(' ', '', strtolower(self::VERSION));
+        $version = str_replace(' ', '', $version);
+
+        return version_compare($version, $currentVersion);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Application.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Application.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Application.php	(revision 345)
@@ -0,0 +1,839 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Helper\DialogHelper;
+
+/**
+ * An Application is the container for a collection of commands.
+ *
+ * It is the main entry point of a Console application.
+ *
+ * This class is optimized for a standard CLI environment.
+ *
+ * Usage:
+ *
+ *     $app = new Application('myapp', '1.0 (stable)');
+ *     $app->add(new SimpleCommand());
+ *     $app->run();
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Application
+{
+    private $commands;
+    private $wantHelps = false;
+    private $runningCommand;
+    private $name;
+    private $version;
+    private $catchExceptions;
+    private $autoExit;
+    private $definition;
+    private $helperSet;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $name    The name of the application
+     * @param string  $version The version of the application
+     *
+     * @api
+     */
+    public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
+    {
+        $this->name = $name;
+        $this->version = $version;
+        $this->catchExceptions = true;
+        $this->autoExit = true;
+        $this->commands = array();
+        $this->helperSet = new HelperSet(array(
+            new FormatterHelper(),
+            new DialogHelper(),
+        ));
+
+        $this->add(new HelpCommand());
+        $this->add(new ListCommand());
+
+        $this->definition = new InputDefinition(array(
+            new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
+
+            new InputOption('--help',           '-h', InputOption::VALUE_NONE, 'Display this help message.'),
+            new InputOption('--quiet',          '-q', InputOption::VALUE_NONE, 'Do not output any message.'),
+            new InputOption('--verbose',        '-v', InputOption::VALUE_NONE, 'Increase verbosity of messages.'),
+            new InputOption('--version',        '-V', InputOption::VALUE_NONE, 'Display this program version.'),
+            new InputOption('--ansi',           '',   InputOption::VALUE_NONE, 'Force ANSI output.'),
+            new InputOption('--no-ansi',        '',   InputOption::VALUE_NONE, 'Disable ANSI output.'),
+            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'),
+        ));
+    }
+
+    /**
+     * Runs the current application.
+     *
+     * @param InputInterface  $input  An Input instance
+     * @param OutputInterface $output An Output instance
+     *
+     * @return integer 0 if everything went fine, or an error code
+     *
+     * @throws \Exception When doRun returns Exception
+     *
+     * @api
+     */
+    public function run(InputInterface $input = null, OutputInterface $output = null)
+    {
+        if (null === $input) {
+            $input = new ArgvInput();
+        }
+
+        if (null === $output) {
+            $output = new ConsoleOutput();
+        }
+
+        try {
+            $statusCode = $this->doRun($input, $output);
+        } catch (\Exception $e) {
+            if (!$this->catchExceptions) {
+                throw $e;
+            }
+
+            $this->renderException($e, $output);
+            $statusCode = $e->getCode();
+
+            $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1;
+        }
+
+        if ($this->autoExit) {
+            if ($statusCode > 255) {
+                $statusCode = 255;
+            }
+            // @codeCoverageIgnoreStart
+            exit($statusCode);
+            // @codeCoverageIgnoreEnd
+        }
+
+        return $statusCode;
+    }
+
+    /**
+     * Runs the current application.
+     *
+     * @param InputInterface  $input  An Input instance
+     * @param OutputInterface $output An Output instance
+     *
+     * @return integer 0 if everything went fine, or an error code
+     */
+    public function doRun(InputInterface $input, OutputInterface $output)
+    {
+        $name = $this->getCommandName($input);
+
+        if (true === $input->hasParameterOption(array('--ansi'))) {
+            $output->setDecorated(true);
+        } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
+            $output->setDecorated(false);
+        }
+
+        if (true === $input->hasParameterOption(array('--help', '-h'))) {
+            if (!$name) {
+                $name = 'help';
+                $input = new ArrayInput(array('command' => 'help'));
+            } else {
+                $this->wantHelps = true;
+            }
+        }
+
+        if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
+            $input->setInteractive(false);
+        }
+
+        if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
+            $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
+        } elseif (true === $input->hasParameterOption(array('--verbose', '-v'))) {
+            $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+        }
+
+        if (true === $input->hasParameterOption(array('--version', '-V'))) {
+            $output->writeln($this->getLongVersion());
+
+            return 0;
+        }
+
+        if (!$name) {
+            $name = 'list';
+            $input = new ArrayInput(array('command' => 'list'));
+        }
+
+        // the command name MUST be the first element of the input
+        $command = $this->find($name);
+
+        $this->runningCommand = $command;
+        $statusCode = $command->run($input, $output);
+        $this->runningCommand = null;
+
+        return is_numeric($statusCode) ? $statusCode : 0;
+    }
+
+    /**
+     * Set a helper set to be used with the command.
+     *
+     * @param HelperSet $helperSet The helper set
+     *
+     * @api
+     */
+    public function setHelperSet(HelperSet $helperSet)
+    {
+        $this->helperSet = $helperSet;
+    }
+
+    /**
+     * Get the helper set associated with the command.
+     *
+     * @return HelperSet The HelperSet instance associated with this command
+     *
+     * @api
+     */
+    public function getHelperSet()
+    {
+        return $this->helperSet;
+    }
+
+    /**
+     * Gets the InputDefinition related to this Application.
+     *
+     * @return InputDefinition The InputDefinition instance
+     */
+    public function getDefinition()
+    {
+        return $this->definition;
+    }
+
+    /**
+     * Gets the help message.
+     *
+     * @return string A help message.
+     */
+    public function getHelp()
+    {
+        $messages = array(
+            $this->getLongVersion(),
+            '',
+            '<comment>Usage:</comment>',
+            sprintf("  [options] command [arguments]\n"),
+            '<comment>Options:</comment>',
+        );
+
+        foreach ($this->getDefinition()->getOptions() as $option) {
+            $messages[] = sprintf('  %-29s %s %s',
+                '<info>--'.$option->getName().'</info>',
+                $option->getShortcut() ? '<info>-'.$option->getShortcut().'</info>' : '  ',
+                $option->getDescription()
+            );
+        }
+
+        return implode("\n", $messages);
+    }
+
+    /**
+     * Sets whether to catch exceptions or not during commands execution.
+     *
+     * @param Boolean $boolean Whether to catch exceptions or not during commands execution
+     *
+     * @api
+     */
+    public function setCatchExceptions($boolean)
+    {
+        $this->catchExceptions = (Boolean) $boolean;
+    }
+
+    /**
+     * Sets whether to automatically exit after a command execution or not.
+     *
+     * @param Boolean $boolean Whether to automatically exit after a command execution or not
+     *
+     * @api
+     */
+    public function setAutoExit($boolean)
+    {
+        $this->autoExit = (Boolean) $boolean;
+    }
+
+    /**
+     * Gets the name of the application.
+     *
+     * @return string The application name
+     *
+     * @api
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets the application name.
+     *
+     * @param string $name The application name
+     *
+     * @api
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * Gets the application version.
+     *
+     * @return string The application version
+     *
+     * @api
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * Sets the application version.
+     *
+     * @param string $version The application version
+     *
+     * @api
+     */
+    public function setVersion($version)
+    {
+        $this->version = $version;
+    }
+
+    /**
+     * Returns the long version of the application.
+     *
+     * @return string The long application version
+     *
+     * @api
+     */
+    public function getLongVersion()
+    {
+        if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
+            return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
+        }
+
+        return '<info>Console Tool</info>';
+    }
+
+    /**
+     * Registers a new command.
+     *
+     * @param string $name The command name
+     *
+     * @return Command The newly created command
+     *
+     * @api
+     */
+    public function register($name)
+    {
+        return $this->add(new Command($name));
+    }
+
+    /**
+     * Adds an array of command objects.
+     *
+     * @param Command[] $commands An array of commands
+     *
+     * @api
+     */
+    public function addCommands(array $commands)
+    {
+        foreach ($commands as $command) {
+            $this->add($command);
+        }
+    }
+
+    /**
+     * Adds a command object.
+     *
+     * If a command with the same name already exists, it will be overridden.
+     *
+     * @param Command $command A Command object
+     *
+     * @return Command The registered command
+     *
+     * @api
+     */
+    public function add(Command $command)
+    {
+        $command->setApplication($this);
+
+        $this->commands[$command->getName()] = $command;
+
+        foreach ($command->getAliases() as $alias) {
+            $this->commands[$alias] = $command;
+        }
+
+        return $command;
+    }
+
+    /**
+     * Returns a registered command by name or alias.
+     *
+     * @param string $name The command name or alias
+     *
+     * @return Command A Command object
+     *
+     * @throws \InvalidArgumentException When command name given does not exist
+     *
+     * @api
+     */
+    public function get($name)
+    {
+        if (!isset($this->commands[$name])) {
+            throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
+        }
+
+        $command = $this->commands[$name];
+
+        if ($this->wantHelps) {
+            $this->wantHelps = false;
+
+            $helpCommand = $this->get('help');
+            $helpCommand->setCommand($command);
+
+            return $helpCommand;
+        }
+
+        return $command;
+    }
+
+    /**
+     * Returns true if the command exists, false otherwise.
+     *
+     * @param string $name The command name or alias
+     *
+     * @return Boolean true if the command exists, false otherwise
+     *
+     * @api
+     */
+    public function has($name)
+    {
+        return isset($this->commands[$name]);
+    }
+
+    /**
+     * Returns an array of all unique namespaces used by currently registered commands.
+     *
+     * It does not returns the global namespace which always exists.
+     *
+     * @return array An array of namespaces
+     */
+    public function getNamespaces()
+    {
+        $namespaces = array();
+        foreach ($this->commands as $command) {
+            $namespaces[] = $this->extractNamespace($command->getName());
+
+            foreach ($command->getAliases() as $alias) {
+                $namespaces[] = $this->extractNamespace($alias);
+            }
+        }
+
+        return array_values(array_unique(array_filter($namespaces)));
+    }
+
+    /**
+     * Finds a registered namespace by a name or an abbreviation.
+     *
+     * @param string $namespace A namespace or abbreviation to search for
+     *
+     * @return string A registered namespace
+     *
+     * @throws \InvalidArgumentException When namespace is incorrect or ambiguous
+     */
+    public function findNamespace($namespace)
+    {
+        $allNamespaces = array();
+        foreach ($this->getNamespaces() as $n) {
+            $allNamespaces[$n] = explode(':', $n);
+        }
+
+        $found = array();
+        foreach (explode(':', $namespace) as $i => $part) {
+            $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces)))));
+
+            if (!isset($abbrevs[$part])) {
+                throw new \InvalidArgumentException(sprintf('There are no commands defined in the "%s" namespace.', $namespace));
+            }
+
+            if (count($abbrevs[$part]) > 1) {
+                throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$namespace])));
+            }
+
+            $found[] = $abbrevs[$part][0];
+        }
+
+        return implode(':', $found);
+    }
+
+    /**
+     * Finds a command by name or alias.
+     *
+     * Contrary to get, this command tries to find the best
+     * match if you give it an abbreviation of a name or alias.
+     *
+     * @param  string $name A command name or a command alias
+     *
+     * @return Command A Command instance
+     *
+     * @throws \InvalidArgumentException When command name is incorrect or ambiguous
+     *
+     * @api
+     */
+    public function find($name)
+    {
+        // namespace
+        $namespace = '';
+        $searchName = $name;
+        if (false !== $pos = strrpos($name, ':')) {
+            $namespace = $this->findNamespace(substr($name, 0, $pos));
+            $searchName = $namespace.substr($name, $pos);
+        }
+
+        // name
+        $commands = array();
+        foreach ($this->commands as $command) {
+            if ($this->extractNamespace($command->getName()) == $namespace) {
+                $commands[] = $command->getName();
+            }
+        }
+
+        $abbrevs = static::getAbbreviations(array_unique($commands));
+        if (isset($abbrevs[$searchName]) && 1 == count($abbrevs[$searchName])) {
+            return $this->get($abbrevs[$searchName][0]);
+        }
+
+        if (isset($abbrevs[$searchName]) && count($abbrevs[$searchName]) > 1) {
+            $suggestions = $this->getAbbreviationSuggestions($abbrevs[$searchName]);
+
+            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
+        }
+
+        // aliases
+        $aliases = array();
+        foreach ($this->commands as $command) {
+            foreach ($command->getAliases() as $alias) {
+                if ($this->extractNamespace($alias) == $namespace) {
+                    $aliases[] = $alias;
+                }
+            }
+        }
+
+        $abbrevs = static::getAbbreviations(array_unique($aliases));
+        if (!isset($abbrevs[$searchName])) {
+            throw new \InvalidArgumentException(sprintf('Command "%s" is not defined.', $name));
+        }
+
+        if (count($abbrevs[$searchName]) > 1) {
+            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($abbrevs[$searchName])));
+        }
+
+        return $this->get($abbrevs[$searchName][0]);
+    }
+
+    /**
+     * Gets the commands (registered in the given namespace if provided).
+     *
+     * The array keys are the full names and the values the command instances.
+     *
+     * @param  string  $namespace A namespace name
+     *
+     * @return array An array of Command instances
+     *
+     * @api
+     */
+    public function all($namespace = null)
+    {
+        if (null === $namespace) {
+            return $this->commands;
+        }
+
+        $commands = array();
+        foreach ($this->commands as $name => $command) {
+            if ($namespace === $this->extractNamespace($name)) {
+                $commands[$name] = $command;
+            }
+        }
+
+        return $commands;
+    }
+
+    /**
+     * Returns an array of possible abbreviations given a set of names.
+     *
+     * @param array $names An array of names
+     *
+     * @return array An array of abbreviations
+     */
+    static public function getAbbreviations($names)
+    {
+        $abbrevs = array();
+        foreach ($names as $name) {
+            for ($len = strlen($name) - 1; $len > 0; --$len) {
+                $abbrev = substr($name, 0, $len);
+                if (!isset($abbrevs[$abbrev])) {
+                    $abbrevs[$abbrev] = array($name);
+                } else {
+                    $abbrevs[$abbrev][] = $name;
+                }
+            }
+        }
+
+        // Non-abbreviations always get entered, even if they aren't unique
+        foreach ($names as $name) {
+            $abbrevs[$name] = array($name);
+        }
+
+        return $abbrevs;
+    }
+
+    /**
+     * Returns a text representation of the Application.
+     *
+     * @param string $namespace An optional namespace name
+     *
+     * @return string A string representing the Application
+     */
+    public function asText($namespace = null)
+    {
+        $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;
+
+        $messages = array($this->getHelp(), '');
+        if ($namespace) {
+            $messages[] = sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $namespace);
+        } else {
+            $messages[] = '<comment>Available commands:</comment>';
+        }
+
+        $width = 0;
+        foreach ($commands as $command) {
+            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
+        }
+        $width += 2;
+
+        // add commands by namespace
+        foreach ($this->sortCommands($commands) as $space => $commands) {
+            if (!$namespace && '_global' !== $space) {
+                $messages[] = '<comment>'.$space.'</comment>';
+            }
+
+            foreach ($commands as $name => $command) {
+                $messages[] = sprintf("  <info>%-${width}s</info> %s", $name, $command->getDescription());
+            }
+        }
+
+        return implode("\n", $messages);
+    }
+
+    /**
+     * Returns an XML representation of the Application.
+     *
+     * @param string  $namespace An optional namespace name
+     * @param Boolean $asDom     Whether to return a DOM or an XML string
+     *
+     * @return string|DOMDocument An XML string representing the Application
+     */
+    public function asXml($namespace = null, $asDom = false)
+    {
+        $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;
+
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->formatOutput = true;
+        $dom->appendChild($xml = $dom->createElement('symfony'));
+
+        $xml->appendChild($commandsXML = $dom->createElement('commands'));
+
+        if ($namespace) {
+            $commandsXML->setAttribute('namespace', $namespace);
+        } else {
+            $namespacesXML = $dom->createElement('namespaces');
+            $xml->appendChild($namespacesXML);
+        }
+
+        // add commands by namespace
+        foreach ($this->sortCommands($commands) as $space => $commands) {
+            if (!$namespace) {
+                $namespaceArrayXML = $dom->createElement('namespace');
+                $namespacesXML->appendChild($namespaceArrayXML);
+                $namespaceArrayXML->setAttribute('id', $space);
+            }
+
+            foreach ($commands as $name => $command) {
+                if ($name !== $command->getName()) {
+                    continue;
+                }
+
+                if (!$namespace) {
+                    $commandXML = $dom->createElement('command');
+                    $namespaceArrayXML->appendChild($commandXML);
+                    $commandXML->appendChild($dom->createTextNode($name));
+                }
+
+                $node = $command->asXml(true)->getElementsByTagName('command')->item(0);
+                $node = $dom->importNode($node, true);
+
+                $commandsXML->appendChild($node);
+            }
+        }
+
+        return $asDom ? $dom : $dom->saveXml();
+    }
+
+    /**
+     * Renders a catched exception.
+     *
+     * @param Exception       $e      An exception instance
+     * @param OutputInterface $output An OutputInterface instance
+     */
+    public function renderException($e, $output)
+    {
+        $strlen = function ($string)
+        {
+            return function_exists('mb_strlen') ? mb_strlen($string, mb_detect_encoding($string)) : strlen($string);
+        };
+
+        do {
+            $title = sprintf('  [%s]  ', get_class($e));
+            $len = $strlen($title);
+            $lines = array();
+            foreach (explode("\n", $e->getMessage()) as $line) {
+                $lines[] = sprintf('  %s  ', $line);
+                $len = max($strlen($line) + 4, $len);
+            }
+
+            $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', $len - $strlen($title)));
+
+            foreach ($lines as $line) {
+                $messages[] = $line.str_repeat(' ', $len - $strlen($line));
+            }
+
+            $messages[] = str_repeat(' ', $len);
+
+            $output->writeln("\n");
+            foreach ($messages as $message) {
+                $output->writeln('<error>'.$message.'</error>');
+            }
+            $output->writeln("\n");
+
+            if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) {
+                $output->writeln('<comment>Exception trace:</comment>');
+
+                // exception related properties
+                $trace = $e->getTrace();
+                array_unshift($trace, array(
+                    'function' => '',
+                    'file'     => $e->getFile() != null ? $e->getFile() : 'n/a',
+                    'line'     => $e->getLine() != null ? $e->getLine() : 'n/a',
+                    'args'     => array(),
+                ));
+
+                for ($i = 0, $count = count($trace); $i < $count; $i++) {
+                    $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
+                    $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
+                    $function = $trace[$i]['function'];
+                    $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
+                    $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+
+                    $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
+                }
+
+                $output->writeln("\n");
+            }
+        } while ($e = $e->getPrevious());
+
+        if (null !== $this->runningCommand) {
+            $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
+            $output->writeln("\n");
+        }
+    }
+
+    /**
+     * Gets the name of the command based on input.
+     *
+     * @param InputInterface $input The input interface
+     *
+     * @return string The command name
+     */
+    protected function getCommandName(InputInterface $input)
+    {
+        return $input->getFirstArgument('command');
+    }
+
+    /**
+     * Sorts commands in alphabetical order.
+     *
+     * @param array $commands An associative array of commands to sort
+     *
+     * @return array A sorted array of commands
+     */
+    private function sortCommands($commands)
+    {
+        $namespacedCommands = array();
+        foreach ($commands as $name => $command) {
+            $key = $this->extractNamespace($name, 1);
+            if (!$key) {
+                $key = '_global';
+            }
+
+            $namespacedCommands[$key][$name] = $command;
+        }
+        ksort($namespacedCommands);
+
+        foreach ($namespacedCommands as &$commands) {
+            ksort($commands);
+        }
+
+        return $namespacedCommands;
+    }
+
+    /**
+     * Returns abbreviated suggestions in string format.
+     *
+     * @param array $abbrevs Abbreviated suggestions to convert
+     *
+     * @return string A formatted string of abbreviated suggestions
+     */
+    private function getAbbreviationSuggestions($abbrevs)
+    {
+        return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
+    }
+
+    private function extractNamespace($name, $limit = null)
+    {
+        $parts = explode(':', $name);
+        array_pop($parts);
+
+        return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/Command.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/Command.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/Command.php	(revision 345)
@@ -0,0 +1,551 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Application;
+
+/**
+ * Base class for all commands.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Command
+{
+    private $application;
+    private $name;
+    private $aliases;
+    private $definition;
+    private $help;
+    private $description;
+    private $ignoreValidationErrors;
+    private $applicationDefinitionMerged;
+    private $code;
+    private $synopsis;
+
+    /**
+     * Constructor.
+     *
+     * @param string $name The name of the command
+     *
+     * @throws \LogicException When the command name is empty
+     *
+     * @api
+     */
+    public function __construct($name = null)
+    {
+        $this->definition = new InputDefinition();
+        $this->ignoreValidationErrors = false;
+        $this->applicationDefinitionMerged = false;
+        $this->aliases = array();
+
+        if (null !== $name) {
+            $this->setName($name);
+        }
+
+        $this->configure();
+
+        if (!$this->name) {
+            throw new \LogicException('The command name cannot be empty.');
+        }
+    }
+
+    /**
+     * Sets the application instance for this command.
+     *
+     * @param Application $application An Application instance
+     *
+     * @api
+     */
+    public function setApplication(Application $application = null)
+    {
+        $this->application = $application;
+    }
+
+    /**
+     * Gets the application instance for this command.
+     *
+     * @return Application An Application instance
+     *
+     * @api
+     */
+    public function getApplication()
+    {
+        return $this->application;
+    }
+
+    /**
+     * Configures the current command.
+     */
+    protected function configure()
+    {
+    }
+
+    /**
+     * Executes the current command.
+     *
+     * This method is not abstract because you can use this class
+     * as a concrete class. In this case, instead of defining the
+     * execute() method, you set the code to execute by passing
+     * a Closure to the setCode() method.
+     *
+     * @param InputInterface  $input  An InputInterface instance
+     * @param OutputInterface $output An OutputInterface instance
+     *
+     * @return integer 0 if everything went fine, or an error code
+     *
+     * @throws \LogicException When this abstract method is not implemented
+     * @see    setCode()
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        throw new \LogicException('You must override the execute() method in the concrete command class.');
+    }
+
+    /**
+     * Interacts with the user.
+     *
+     * @param InputInterface  $input  An InputInterface instance
+     * @param OutputInterface $output An OutputInterface instance
+     */
+    protected function interact(InputInterface $input, OutputInterface $output)
+    {
+    }
+
+    /**
+     * Initializes the command just after the input has been validated.
+     *
+     * This is mainly useful when a lot of commands extends one main command
+     * where some things need to be initialized based on the input arguments and options.
+     *
+     * @param InputInterface  $input  An InputInterface instance
+     * @param OutputInterface $output An OutputInterface instance
+     */
+    protected function initialize(InputInterface $input, OutputInterface $output)
+    {
+    }
+
+    /**
+     * Runs the command.
+     *
+     * The code to execute is either defined directly with the
+     * setCode() method or by overriding the execute() method
+     * in a sub-class.
+     *
+     * @param InputInterface  $input  An InputInterface instance
+     * @param OutputInterface $output An OutputInterface instance
+     *
+     * @see setCode()
+     * @see execute()
+     *
+     * @api
+     */
+    public function run(InputInterface $input, OutputInterface $output)
+    {
+        // force the creation of the synopsis before the merge with the app definition
+        $this->getSynopsis();
+
+        // add the application arguments and options
+        $this->mergeApplicationDefinition();
+
+        // bind the input against the command specific arguments/options
+        try {
+            $input->bind($this->definition);
+        } catch (\Exception $e) {
+            if (!$this->ignoreValidationErrors) {
+                throw $e;
+            }
+        }
+
+        $this->initialize($input, $output);
+
+        if ($input->isInteractive()) {
+            $this->interact($input, $output);
+        }
+
+        $input->validate();
+
+        if ($this->code) {
+            return call_user_func($this->code, $input, $output);
+        }
+
+        return $this->execute($input, $output);
+    }
+
+    /**
+     * Sets the code to execute when running this command.
+     *
+     * If this method is used, it overrides the code defined
+     * in the execute() method.
+     *
+     * @param \Closure $code A \Closure
+     *
+     * @return Command The current instance
+     *
+     * @see execute()
+     *
+     * @api
+     */
+    public function setCode(\Closure $code)
+    {
+        $this->code = $code;
+
+        return $this;
+    }
+
+    /**
+     * Merges the application definition with the command definition.
+     */
+    private function mergeApplicationDefinition()
+    {
+        if (null === $this->application || true === $this->applicationDefinitionMerged) {
+            return;
+        }
+
+        $this->definition->setArguments(array_merge(
+            $this->application->getDefinition()->getArguments(),
+            $this->definition->getArguments()
+        ));
+
+        $this->definition->addOptions($this->application->getDefinition()->getOptions());
+
+        $this->applicationDefinitionMerged = true;
+    }
+
+    /**
+     * Sets an array of argument and option instances.
+     *
+     * @param array|Definition $definition An array of argument and option instances or a definition instance
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function setDefinition($definition)
+    {
+        if ($definition instanceof InputDefinition) {
+            $this->definition = $definition;
+        } else {
+            $this->definition->setDefinition($definition);
+        }
+
+        $this->applicationDefinitionMerged = false;
+
+        return $this;
+    }
+
+    /**
+     * Gets the InputDefinition attached to this Command.
+     *
+     * @return InputDefinition An InputDefinition instance
+     *
+     * @api
+     */
+    public function getDefinition()
+    {
+        return $this->definition;
+    }
+
+    /**
+     * Adds an argument.
+     *
+     * @param string  $name        The argument name
+     * @param integer $mode        The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+     * @param string  $description A description text
+     * @param mixed   $default     The default value (for InputArgument::OPTIONAL mode only)
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function addArgument($name, $mode = null, $description = '', $default = null)
+    {
+        $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
+
+        return $this;
+    }
+
+    /**
+     * Adds an option.
+     *
+     * @param string  $name        The option name
+     * @param string  $shortcut    The shortcut (can be null)
+     * @param integer $mode        The option mode: One of the InputOption::VALUE_* constants
+     * @param string  $description A description text
+     * @param mixed   $default     The default value (must be null for InputOption::VALUE_REQUIRED or self::VALUE_NONE)
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
+    {
+        $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
+
+        return $this;
+    }
+
+    /**
+     * Sets the name of the command.
+     *
+     * This method can set both the namespace and the name if
+     * you separate them by a colon (:)
+     *
+     *     $command->setName('foo:bar');
+     *
+     * @param string $name The command name
+     *
+     * @return Command The current instance
+     *
+     * @throws \InvalidArgumentException When command name given is empty
+     *
+     * @api
+     */
+    public function setName($name)
+    {
+        $this->validateName($name);
+
+        $this->name = $name;
+
+        return $this;
+    }
+
+    /**
+     * Returns the command name.
+     *
+     * @return string The command name
+     *
+     * @api
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets the description for the command.
+     *
+     * @param string $description The description for the command
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function setDescription($description)
+    {
+        $this->description = $description;
+
+        return $this;
+    }
+
+    /**
+     * Returns the description for the command.
+     *
+     * @return string The description for the command
+     *
+     * @api
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * Sets the help for the command.
+     *
+     * @param string $help The help for the command
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function setHelp($help)
+    {
+        $this->help = $help;
+
+        return $this;
+    }
+
+    /**
+     * Returns the help for the command.
+     *
+     * @return string The help for the command
+     *
+     * @api
+     */
+    public function getHelp()
+    {
+        return $this->help;
+    }
+
+    /**
+     * Returns the processed help for the command replacing the %command.name% and
+     * %command.full_name% patterns with the real values dynamically.
+     *
+     * @return string  The processed help for the command
+     */
+    public function getProcessedHelp()
+    {
+        $name = $this->name;
+
+        $placeholders = array(
+            '%command.name%',
+            '%command.full_name%'
+        );
+        $replacements = array(
+            $name,
+            $_SERVER['PHP_SELF'].' '.$name
+        );
+
+        return str_replace($placeholders, $replacements, $this->getHelp());
+    }
+
+    /**
+     * Sets the aliases for the command.
+     *
+     * @param array $aliases An array of aliases for the command
+     *
+     * @return Command The current instance
+     *
+     * @api
+     */
+    public function setAliases($aliases)
+    {
+        foreach ($aliases as $alias) {
+            $this->validateName($alias);
+        }
+
+        $this->aliases = $aliases;
+
+        return $this;
+    }
+
+    /**
+     * Returns the aliases for the command.
+     *
+     * @return array An array of aliases for the command
+     *
+     * @api
+     */
+    public function getAliases()
+    {
+        return $this->aliases;
+    }
+
+    /**
+     * Returns the synopsis for the command.
+     *
+     * @return string The synopsis
+     */
+    public function getSynopsis()
+    {
+        if (null === $this->synopsis) {
+            $this->synopsis = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis()));
+        }
+
+        return $this->synopsis;
+    }
+
+    /**
+     * Gets a helper instance by name.
+     *
+     * @param string $name The helper name
+     *
+     * @return mixed The helper value
+     *
+     * @throws \InvalidArgumentException if the helper is not defined
+     *
+     * @api
+     */
+    public function getHelper($name)
+    {
+        return $this->application->getHelperSet()->get($name);
+    }
+
+    /**
+     * Returns a text representation of the command.
+     *
+     * @return string A string representing the command
+     */
+    public function asText()
+    {
+        $messages = array(
+            '<comment>Usage:</comment>',
+            ' '.$this->getSynopsis(),
+            '',
+        );
+
+        if ($this->getAliases()) {
+            $messages[] = '<comment>Aliases:</comment> <info>'.implode(', ', $this->getAliases()).'</info>';
+        }
+
+        $messages[] = $this->definition->asText();
+
+        if ($help = $this->getProcessedHelp()) {
+            $messages[] = '<comment>Help:</comment>';
+            $messages[] = ' '.implode("\n ", explode("\n", $help))."\n";
+        }
+
+        return implode("\n", $messages);
+    }
+
+    /**
+     * Returns an XML representation of the command.
+     *
+     * @param Boolean $asDom Whether to return a DOM or an XML string
+     *
+     * @return string|DOMDocument An XML string representing the command
+     */
+    public function asXml($asDom = false)
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->formatOutput = true;
+        $dom->appendChild($commandXML = $dom->createElement('command'));
+        $commandXML->setAttribute('id', $this->name);
+        $commandXML->setAttribute('name', $this->name);
+
+        $commandXML->appendChild($usageXML = $dom->createElement('usage'));
+        $usageXML->appendChild($dom->createTextNode(sprintf($this->getSynopsis(), '')));
+
+        $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+        $descriptionXML->appendChild($dom->createTextNode(implode("\n ", explode("\n", $this->getDescription()))));
+
+        $commandXML->appendChild($helpXML = $dom->createElement('help'));
+        $help = $this->help;
+        $helpXML->appendChild($dom->createTextNode(implode("\n ", explode("\n", $help))));
+
+        $commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
+        foreach ($this->getAliases() as $alias) {
+            $aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
+            $aliasXML->appendChild($dom->createTextNode($alias));
+        }
+
+        $definition = $this->definition->asXml(true);
+        $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('arguments')->item(0), true));
+        $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('options')->item(0), true));
+
+        return $asDom ? $dom : $dom->saveXml();
+    }
+
+    private function validateName($name)
+    {
+        if (!preg_match('/^[^\:]+(\:[^\:]+)*$/', $name)) {
+            throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/HelpCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/HelpCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/HelpCommand.php	(revision 345)
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * HelpCommand displays the help for a given command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class HelpCommand extends Command
+{
+    private $command;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->ignoreValidationErrors = true;
+
+        $this
+            ->setDefinition(array(
+                new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
+                new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
+            ))
+            ->setName('help')
+            ->setDescription('Displays help for a command')
+            ->setHelp(<<<EOF
+The <info>help</info> command displays help for a given command:
+
+  <info>./symfony help list</info>
+
+You can also output the help as XML by using the <comment>--xml</comment> option:
+
+  <info>./symfony help --xml list</info>
+EOF
+            );
+    }
+
+    /**
+     * Sets the command
+     *
+     * @param Command $command The command to set
+     */
+    public function setCommand(Command $command)
+    {
+        $this->command = $command;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (null === $this->command) {
+            $this->command = $this->getApplication()->get($input->getArgument('command_name'));
+        }
+
+        if ($input->getOption('xml')) {
+            $output->writeln($this->command->asXml(), OutputInterface::OUTPUT_RAW);
+        } else {
+            $output->writeln($this->command->asText());
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/ListCommand.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/ListCommand.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Command/ListCommand.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * ListCommand displays the list of all available commands for the application.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ListCommand extends Command
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this
+            ->setDefinition(array(
+                new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
+                new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
+            ))
+            ->setName('list')
+            ->setDescription('Lists commands')
+            ->setHelp(<<<EOF
+The <info>list</info> command lists all commands:
+
+  <info>./symfony list</info>
+
+You can also display the commands for a specific namespace:
+
+  <info>./symfony list test</info>
+
+You can also output the information as XML by using the <comment>--xml</comment> option:
+
+  <info>./symfony list --xml</info>
+EOF
+            );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if ($input->getOption('xml')) {
+            $output->writeln($this->getApplication()->asXml($input->getArgument('namespace')), OutputInterface::OUTPUT_RAW);
+        } else {
+            $output->writeln($this->getApplication()->asText($input->getArgument('namespace')));
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatter.php	(revision 345)
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter class for console output.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+class OutputFormatter implements OutputFormatterInterface
+{
+    private $decorated;
+    private $styles = array();
+
+    /**
+     * Initializes console output formatter.
+     *
+     * @param   Boolean $decorated  Whether this formatter should actually decorate strings
+     * @param   array   $styles     Array of "name => FormatterStyle" instance
+     *
+     * @api
+     */
+    public function __construct($decorated = null, array $styles = array())
+    {
+        $this->decorated = (Boolean) $decorated;
+
+        $this->setStyle('error',    new OutputFormatterStyle('white', 'red'));
+        $this->setStyle('info',     new OutputFormatterStyle('green'));
+        $this->setStyle('comment',  new OutputFormatterStyle('yellow'));
+        $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
+
+        foreach ($styles as $name => $style) {
+            $this->setStyle($name, $style);
+        }
+    }
+
+    /**
+     * Sets the decorated flag.
+     *
+     * @param Boolean $decorated Whether to decorated the messages or not
+     *
+     * @api
+     */
+    public function setDecorated($decorated)
+    {
+        $this->decorated = (Boolean) $decorated;
+    }
+
+    /**
+     * Gets the decorated flag.
+     *
+     * @return Boolean true if the output will decorate messages, false otherwise
+     *
+     * @api
+     */
+    public function isDecorated()
+    {
+        return $this->decorated;
+    }
+
+    /**
+     * Sets a new style.
+     *
+     * @param string                        $name  The style name
+     * @param OutputFormatterStyleInterface $style The style instance
+     *
+     * @api
+     */
+    public function setStyle($name, OutputFormatterStyleInterface $style)
+    {
+        $this->styles[strtolower($name)] = $style;
+    }
+
+    /**
+     * Checks if output formatter has style with specified name.
+     *
+     * @param   string  $name
+     *
+     * @return  Boolean
+     *
+     * @api
+     */
+    public function hasStyle($name)
+    {
+        return isset($this->styles[strtolower($name)]);
+    }
+
+    /**
+     * Gets style options from style with specified name.
+     *
+     * @param   string  $name
+     *
+     * @return  OutputFormatterStyleInterface
+     *
+     * @api
+     */
+    public function getStyle($name)
+    {
+        if (!$this->hasStyle($name)) {
+            throw new \InvalidArgumentException('Undefined style: ' . $name);
+        }
+
+        return $this->styles[strtolower($name)];
+    }
+
+    /**
+     * Formats a message according to the given styles.
+     *
+     * @param  string $message The message to style
+     *
+     * @return string The styled message
+     *
+     * @api
+     */
+    public function format($message)
+    {
+        return preg_replace_callback('#<([a-z][a-z0-9_=;-]+)>(.*?)</\\1?>#i', array($this, 'replaceStyle'), $message);
+    }
+
+    /**
+     * Replaces style of the output.
+     *
+     * @param array $match
+     *
+     * @return string The replaced style
+     */
+    private function replaceStyle($match)
+    {
+        if (!$this->isDecorated()) {
+            return $match[2];
+        }
+
+        if (isset($this->styles[strtolower($match[1])])) {
+            $style = $this->styles[strtolower($match[1])];
+        } else {
+            $style = $this->createStyleFromString($match[1]);
+
+            if (false === $style) {
+                return $match[0];
+            }
+        }
+
+        return $style->apply($this->format($match[2]));
+    }
+
+    /**
+     * Tries to create new style instance from string.
+     *
+     * @param   string  $string
+     *
+     * @return  Symfony\Component\Console\Format\FormatterStyle|Boolean false if string is not format string
+     */
+    private function createStyleFromString($string)
+    {
+        if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
+            return false;
+        }
+
+        $style = new OutputFormatterStyle();
+        foreach ($matches as $match) {
+            array_shift($match);
+
+            if ('fg' == $match[0]) {
+                $style->setForeground($match[1]);
+            } elseif ('bg' == $match[0]) {
+                $style->setBackground($match[1]);
+            } else {
+                $style->setOption($match[1]);
+            }
+        }
+
+        return $style;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterInterface.php	(revision 345)
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+interface OutputFormatterInterface
+{
+    /**
+     * Sets the decorated flag.
+     *
+     * @param Boolean $decorated Whether to decorated the messages or not
+     *
+     * @api
+     */
+    function setDecorated($decorated);
+
+    /**
+     * Gets the decorated flag.
+     *
+     * @return Boolean true if the output will decorate messages, false otherwise
+     *
+     * @api
+     */
+    function isDecorated();
+
+    /**
+     * Sets a new style.
+     *
+     * @param string                        $name  The style name
+     * @param OutputFormatterStyleInterface $style The style instance
+     *
+     * @api
+     */
+    function setStyle($name, OutputFormatterStyleInterface $style);
+
+    /**
+     * Checks if output formatter has style with specified name.
+     *
+     * @param   string  $name
+     *
+     * @return  Boolean
+     *
+     * @api
+     */
+    function hasStyle($name);
+
+    /**
+     * Gets style options from style with specified name.
+     *
+     * @param   string  $name
+     *
+     * @return  OutputFormatterStyleInterface
+     *
+     * @api
+     */
+    function getStyle($name);
+
+    /**
+     * Formats a message according to the given styles.
+     *
+     * @param  string $message The message to style
+     *
+     * @return string The styled message
+     *
+     * @api
+     */
+    function format($message);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyle.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyle.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyle.php	(revision 345)
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+    static private $availableForegroundColors = array(
+        'black'     => 30,
+        'red'       => 31,
+        'green'     => 32,
+        'yellow'    => 33,
+        'blue'      => 34,
+        'magenta'   => 35,
+        'cyan'      => 36,
+        'white'     => 37
+    );
+    static private $availableBackgroundColors = array(
+        'black'     => 40,
+        'red'       => 41,
+        'green'     => 42,
+        'yellow'    => 43,
+        'blue'      => 44,
+        'magenta'   => 45,
+        'cyan'      => 46,
+        'white'     => 47
+    );
+    static private $availableOptions = array(
+        'bold'          => 1,
+        'underscore'    => 4,
+        'blink'         => 5,
+        'reverse'       => 7,
+        'conceal'       => 8
+    );
+
+    private $foreground;
+    private $background;
+    private $options = array();
+
+    /**
+     * Initializes output formatter style.
+     *
+     * @param   string  $foreground     style foreground color name
+     * @param   string  $background     style background color name
+     * @param   array   $options        style options
+     *
+     * @api
+     */
+    public function __construct($foreground = null, $background = null, array $options = array())
+    {
+        if (null !== $foreground) {
+            $this->setForeground($foreground);
+        }
+        if (null !== $background) {
+            $this->setBackground($background);
+        }
+        if (count($options)) {
+            $this->setOptions($options);
+        }
+    }
+
+    /**
+     * Sets style foreground color.
+     *
+     * @param   string  $color  color name
+     *
+     * @api
+     */
+    public function setForeground($color = null)
+    {
+        if (null === $color) {
+            $this->foreground = null;
+
+            return;
+        }
+
+        if (!isset(static::$availableForegroundColors[$color])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid foreground color specified: "%s". Expected one of (%s)',
+                $color,
+                implode(', ', array_keys(static::$availableForegroundColors))
+            ));
+        }
+
+        $this->foreground = static::$availableForegroundColors[$color];
+    }
+
+    /**
+     * Sets style background color.
+     *
+     * @param   string  $color  color name
+     *
+     * @api
+     */
+    public function setBackground($color = null)
+    {
+        if (null === $color) {
+            $this->background = null;
+
+            return;
+        }
+
+        if (!isset(static::$availableBackgroundColors[$color])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid background color specified: "%s". Expected one of (%s)',
+                $color,
+                implode(', ', array_keys(static::$availableBackgroundColors))
+            ));
+        }
+
+        $this->background = static::$availableBackgroundColors[$color];
+    }
+
+    /**
+     * Sets some specific style option.
+     *
+     * @param   string  $option     option name
+     *
+     * @api
+     */
+    public function setOption($option)
+    {
+        if (!isset(static::$availableOptions[$option])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid option specified: "%s". Expected one of (%s)',
+                $option,
+                implode(', ', array_keys(static::$availableOptions))
+            ));
+        }
+
+        if (false === array_search(static::$availableOptions[$option], $this->options)) {
+            $this->options[] = static::$availableOptions[$option];
+        }
+    }
+
+    /**
+     * Unsets some specific style option.
+     *
+     * @param   string  $option     option name
+     */
+    public function unsetOption($option)
+    {
+        if (!isset(static::$availableOptions[$option])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid option specified: "%s". Expected one of (%s)',
+                $option,
+                implode(', ', array_keys(static::$availableOptions))
+            ));
+        }
+
+        $pos = array_search(static::$availableOptions[$option], $this->options);
+        if (false !== $pos) {
+            unset($this->options[$pos]);
+        }
+    }
+
+    /**
+     * Set multiple style options at once.
+     *
+     * @param   array   $options
+     */
+    public function setOptions(array $options)
+    {
+        $this->options = array();
+
+        foreach ($options as $option) {
+            $this->setOption($option);
+        }
+    }
+
+    /**
+     * Applies the style to a given text.
+     *
+     * @param string $text The text to style
+     *
+     * @return string
+     */
+    public function apply($text)
+    {
+        $codes = array();
+
+        if (null !== $this->foreground) {
+            $codes[] = $this->foreground;
+        }
+        if (null !== $this->background) {
+            $codes[] = $this->background;
+        }
+        if (count($this->options)) {
+            $codes = array_merge($codes, $this->options);
+        }
+
+        return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style interface for defining styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+interface OutputFormatterStyleInterface
+{
+    /**
+     * Sets style foreground color.
+     *
+     * @param   string  $color  color name
+     *
+     * @api
+     */
+    function setForeground($color = null);
+
+    /**
+     * Sets style background color.
+     *
+     * @param   string  $color  color name
+     *
+     * @api
+     */
+    function setBackground($color = null);
+
+    /**
+     * Sets some specific style option.
+     *
+     * @param   string  $option     option name
+     *
+     * @api
+     */
+    function setOption($option);
+
+    /**
+     * Unsets some specific style option.
+     *
+     * @param   string  $option     option name
+     */
+    function unsetOption($option);
+
+    /**
+     * Set multiple style options at once.
+     *
+     * @param   array   $options
+     */
+    function setOptions(array $options);
+
+    /**
+     * Applies the style to a given text.
+     *
+     * @param string $text The text to style
+     *
+     * @return string
+     */
+    function apply($text);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/DialogHelper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/DialogHelper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/DialogHelper.php	(revision 345)
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * The Dialog class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DialogHelper extends Helper
+{
+    /**
+     * Asks a question to the user.
+     *
+     * @param OutputInterface $output
+     * @param string|array    $question The question to ask
+     * @param string          $default  The default answer if none is given by the user
+     *
+     * @return string The user answer
+     */
+    public function ask(OutputInterface $output, $question, $default = null)
+    {
+        // @codeCoverageIgnoreStart
+        $output->write($question);
+
+        $ret = trim(fgets(STDIN));
+
+        return $ret ? $ret : $default;
+        // @codeCoverageIgnoreEnd
+    }
+
+    /**
+     * Asks a confirmation to the user.
+     *
+     * The question will be asked until the user answer by nothing, yes, or no.
+     *
+     * @param OutputInterface $output
+     * @param string|array    $question The question to ask
+     * @param Boolean         $default  The default answer if the user enters nothing
+     *
+     * @return Boolean true if the user has confirmed, false otherwise
+     */
+    public function askConfirmation(OutputInterface $output, $question, $default = true)
+    {
+        // @codeCoverageIgnoreStart
+        $answer = 'z';
+        while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
+            $answer = $this->ask($output, $question);
+        }
+
+        if (false === $default) {
+            return $answer && 'y' == strtolower($answer[0]);
+        }
+
+        return !$answer || 'y' == strtolower($answer[0]);
+        // @codeCoverageIgnoreEnd
+    }
+
+    /**
+     * Asks for a value and validates the response.
+     *
+     * The validator receives the data to validate. It must return the
+     * validated data when the data is valid and throw an exception
+     * otherwise.
+     *
+     * @param OutputInterface $output
+     * @param string|array    $question
+     * @param callback        $validator A PHP callback
+     * @param integer         $attempts Max number of times to ask before giving up (false by default, which means infinite)
+     * @param string          $default  The default answer if none is given by the user
+     *
+     * @return mixed
+     *
+     * @throws \Exception When any of the validator returns an error
+     */
+    public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null)
+    {
+        // @codeCoverageIgnoreStart
+        $error = null;
+        while (false === $attempts || $attempts--) {
+            if (null !== $error) {
+                $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
+            }
+
+            $value = $this->ask($output, $question, $default);
+
+            try {
+                return call_user_func($validator, $value);
+            } catch (\Exception $error) {
+            }
+        }
+
+        throw $error;
+        // @codeCoverageIgnoreEnd
+    }
+
+    /**
+     * Returns the helper's canonical name
+     */
+    public function getName()
+    {
+        return 'dialog';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/FormatterHelper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/FormatterHelper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/FormatterHelper.php	(revision 345)
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * The Formatter class provides helpers to format messages.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FormatterHelper extends Helper
+{
+    /**
+     * Formats a message within a section.
+     *
+     * @param string  $section The section name
+     * @param string  $message The message
+     * @param string  $style   The style to apply to the section
+     */
+    public function formatSection($section, $message, $style = 'info')
+    {
+        return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
+    }
+
+    /**
+     * Formats a message as a block of text.
+     *
+     * @param string|array $messages The message to write in the block
+     * @param string       $style    The style to apply to the whole block
+     * @param Boolean      $large    Whether to return a large block
+     *
+     * @return string The formatter message
+     */
+    public function formatBlock($messages, $style, $large = false)
+    {
+        $messages = (array) $messages;
+
+        $len = 0;
+        $lines = array();
+        foreach ($messages as $message) {
+            $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
+            $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
+        }
+
+        $messages = $large ? array(str_repeat(' ', $len)) : array();
+        foreach ($lines as $line) {
+            $messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
+        }
+        if ($large) {
+            $messages[] = str_repeat(' ', $len);
+        }
+
+        foreach ($messages as &$message) {
+            $message = sprintf('<%s>%s</%s>', $style, $message, $style);
+        }
+
+        return implode("\n", $messages);
+    }
+
+    /**
+     * Returns the length of a string, uses mb_strlen if it is available.
+     *
+     * @param string $string The string to check its length
+     *
+     * @return integer The length of the string
+     */
+    private function strlen($string)
+    {
+        return function_exists('mb_strlen') ? mb_strlen($string, mb_detect_encoding($string)) : strlen($string);
+    }
+
+    /**
+     * Returns the helper's canonical name
+     *
+     * @return string The canonical name of the helper
+     */
+    public function getName()
+    {
+        return 'formatter';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/Helper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/Helper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/Helper.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Helper is the base class for all helper classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Helper implements HelperInterface
+{
+    protected $helperSet = null;
+
+    /**
+     * Sets the helper set associated with this helper.
+     *
+     * @param HelperSet $helperSet A HelperSet instance
+     */
+    public function setHelperSet(HelperSet $helperSet = null)
+    {
+        $this->helperSet = $helperSet;
+    }
+
+    /**
+     * Gets the helper set associated with this helper.
+     *
+     * @return HelperSet A HelperSet instance
+     */
+    public function getHelperSet()
+    {
+        return $this->helperSet;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperInterface.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * HelperInterface is the interface all helpers must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface HelperInterface
+{
+    /**
+     * Sets the helper set associated with this helper.
+     *
+     * @param HelperSet $helperSet A HelperSet instance
+     *
+     * @api
+     */
+    function setHelperSet(HelperSet $helperSet = null);
+
+    /**
+     * Gets the helper set associated with this helper.
+     *
+     * @return HelperSet A HelperSet instance
+     *
+     * @api
+     */
+    function getHelperSet();
+
+    /**
+     * Returns the canonical name of this helper.
+     *
+     * @return string The canonical name
+     *
+     * @api
+     */
+    function getName();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperSet.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperSet.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Helper/HelperSet.php	(revision 345)
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * HelperSet represents a set of helpers to be used with a command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class HelperSet
+{
+    private $helpers;
+    private $command;
+
+    /**
+     * @param Helper[] $helpers An array of helper.
+     */
+    public function __construct(array $helpers = array())
+    {
+        $this->helpers = array();
+        foreach ($helpers as $alias => $helper) {
+            $this->set($helper, is_int($alias) ? null : $alias);
+        }
+    }
+
+    /**
+     * Sets a helper.
+     *
+     * @param HelperInterface $helper The helper instance
+     * @param string          $alias  An alias
+     */
+    public function set(HelperInterface $helper, $alias = null)
+    {
+        $this->helpers[$helper->getName()] = $helper;
+        if (null !== $alias) {
+            $this->helpers[$alias] = $helper;
+        }
+
+        $helper->setHelperSet($this);
+    }
+
+    /**
+     * Returns true if the helper if defined.
+     *
+     * @param string  $name The helper name
+     *
+     * @return Boolean true if the helper is defined, false otherwise
+     */
+    public function has($name)
+    {
+        return isset($this->helpers[$name]);
+    }
+
+    /**
+     * Gets a helper value.
+     *
+     * @param string $name The helper name
+     *
+     * @return HelperInterface The helper instance
+     *
+     * @throws \InvalidArgumentException if the helper is not defined
+     */
+    public function get($name)
+    {
+        if (!$this->has($name)) {
+            throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
+        }
+
+        return $this->helpers[$name];
+    }
+
+    /**
+     * Sets the command associated with this helper set.
+     *
+     * @param Command $command A Command instance
+     */
+    public function setCommand(Command $command = null)
+    {
+        $this->command = $command;
+    }
+
+    /**
+     * Gets the command associated with this helper set.
+     *
+     * @return Command A Command instance
+     */
+    public function getCommand()
+    {
+        return $this->command;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArgvInput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArgvInput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArgvInput.php	(revision 345)
@@ -0,0 +1,307 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArgvInput represents an input coming from the CLI arguments.
+ *
+ * Usage:
+ *
+ *     $input = new ArgvInput();
+ *
+ * By default, the `$_SERVER['argv']` array is used for the input values.
+ *
+ * This can be overridden by explicitly passing the input values in the constructor:
+ *
+ *     $input = new ArgvInput($_SERVER['argv']);
+ *
+ * If you pass it yourself, don't forget that the first element of the array
+ * is the name of the running program.
+ *
+ * When passing an argument to the constructor, be sure that it respects
+ * the same rules as the argv one. It's almost always better to use the
+ * `StringInput` when you want to provide your own input.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+ * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
+ *
+ * @api
+ */
+class ArgvInput extends Input
+{
+    private $tokens;
+    private $parsed;
+
+    /**
+     * Constructor.
+     *
+     * @param array           $argv An array of parameters from the CLI (in the argv format)
+     * @param InputDefinition $definition A InputDefinition instance
+     *
+     * @api
+     */
+    public function __construct(array $argv = null, InputDefinition $definition = null)
+    {
+        if (null === $argv) {
+            $argv = $_SERVER['argv'];
+        }
+
+        // strip the program name
+        array_shift($argv);
+
+        $this->tokens = $argv;
+
+        parent::__construct($definition);
+    }
+
+    protected function setTokens(array $tokens)
+    {
+        $this->tokens = $tokens;
+    }
+
+    /**
+     * Processes command line arguments.
+     */
+    protected function parse()
+    {
+        $this->parsed = $this->tokens;
+        while (null !== $token = array_shift($this->parsed)) {
+            if ('--' === substr($token, 0, 2)) {
+                $this->parseLongOption($token);
+            } elseif ('-' === $token[0]) {
+                $this->parseShortOption($token);
+            } else {
+                $this->parseArgument($token);
+            }
+        }
+    }
+
+    /**
+     * Parses a short option.
+     *
+     * @param string $token The current token.
+     */
+    private function parseShortOption($token)
+    {
+        $name = substr($token, 1);
+
+        if (strlen($name) > 1) {
+            if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
+                // an option with a value (with no space)
+                $this->addShortOption($name[0], substr($name, 1));
+            } else {
+                $this->parseShortOptionSet($name);
+            }
+        } else {
+            $this->addShortOption($name, null);
+        }
+    }
+
+    /**
+     * Parses a short option set.
+     *
+     * @param string $name The current token
+     *
+     * @throws \RuntimeException When option given doesn't exist
+     */
+    private function parseShortOptionSet($name)
+    {
+        $len = strlen($name);
+        for ($i = 0; $i < $len; $i++) {
+            if (!$this->definition->hasShortcut($name[$i])) {
+                throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
+            }
+
+            $option = $this->definition->getOptionForShortcut($name[$i]);
+            if ($option->acceptValue()) {
+                $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
+
+                break;
+            } else {
+                $this->addLongOption($option->getName(), true);
+            }
+        }
+    }
+
+    /**
+     * Parses a long option.
+     *
+     * @param string $token The current token
+     */
+    private function parseLongOption($token)
+    {
+        $name = substr($token, 2);
+
+        if (false !== $pos = strpos($name, '=')) {
+            $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
+        } else {
+            $this->addLongOption($name, null);
+        }
+    }
+
+    /**
+     * Parses an argument.
+     *
+     * @param string $token The current token
+     *
+     * @throws \RuntimeException When too many arguments are given
+     */
+    private function parseArgument($token)
+    {
+        $c = count($this->arguments);
+
+        // if input is expecting another argument, add it
+        if ($this->definition->hasArgument($c)) {
+            $arg = $this->definition->getArgument($c);
+            $this->arguments[$arg->getName()] = $arg->isArray()? array($token) : $token;
+
+        // if last argument isArray(), append token to last argument
+        } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
+            $arg = $this->definition->getArgument($c - 1);
+            $this->arguments[$arg->getName()][] = $token;
+
+        // unexpected argument
+        } else {
+            throw new \RuntimeException('Too many arguments.');
+        }
+    }
+
+    /**
+     * Adds a short option value.
+     *
+     * @param string $shortcut The short option key
+     * @param mixed  $value    The value for the option
+     *
+     * @throws \RuntimeException When option given doesn't exist
+     */
+    private function addShortOption($shortcut, $value)
+    {
+        if (!$this->definition->hasShortcut($shortcut)) {
+            throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
+        }
+
+        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+    }
+
+    /**
+     * Adds a long option value.
+     *
+     * @param string $name  The long option key
+     * @param mixed  $value The value for the option
+     *
+     * @throws \RuntimeException When option given doesn't exist
+     */
+    private function addLongOption($name, $value)
+    {
+        if (!$this->definition->hasOption($name)) {
+            throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
+        }
+
+        $option = $this->definition->getOption($name);
+
+        if (null === $value && $option->acceptValue()) {
+            // if option accepts an optional or mandatory argument
+            // let's see if there is one provided
+            $next = array_shift($this->parsed);
+            if ('-' !== $next[0]) {
+                $value = $next;
+            } else {
+                array_unshift($this->parsed, $next);
+            }
+        }
+
+        if (null === $value) {
+            if ($option->isValueRequired()) {
+                throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
+            }
+
+            $value = $option->isValueOptional() ? $option->getDefault() : true;
+        }
+
+        if ($option->isArray()) {
+            $this->options[$name][] = $value;
+        } else {
+            $this->options[$name] = $value;
+        }
+    }
+
+    /**
+     * Returns the first argument from the raw parameters (not parsed).
+     *
+     * @return string The value of the first argument or null otherwise
+     */
+    public function getFirstArgument()
+    {
+        foreach ($this->tokens as $token) {
+            if ($token && '-' === $token[0]) {
+                continue;
+            }
+
+            return $token;
+        }
+    }
+
+    /**
+     * Returns true if the raw parameters (not parsed) contains a value.
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+     *
+     * @return Boolean true if the value is contained in the raw parameters
+     */
+    public function hasParameterOption($values)
+    {
+        $values = (array) $values;
+
+        foreach ($this->tokens as $v) {
+            if (in_array($v, $values)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the value of a raw option (not parsed).
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+     * @param mixed $default The default value to return if no result is found
+     * @return mixed The option value
+     */
+    public function getParameterOption($values, $default = false)
+    {
+        $values = (array) $values;
+
+        $tokens = $this->tokens;
+        while ($token = array_shift($tokens)) {
+            foreach ($values as $value) {
+                if (0 === strpos($token, $value)) {
+                    if (false !== $pos = strpos($token, '=')) {
+                        return substr($token, $pos + 1);
+                    }
+
+                    return array_shift($tokens);
+                }
+            }
+        }
+
+        return $default;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArrayInput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArrayInput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/ArrayInput.php	(revision 345)
@@ -0,0 +1,190 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArrayInput represents an input provided as an array.
+ *
+ * Usage:
+ *
+ *     $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ArrayInput extends Input
+{
+    private $parameters;
+
+    /**
+     * Constructor.
+     *
+     * @param array           $parameters An array of parameters
+     * @param InputDefinition $definition A InputDefinition instance
+     *
+     * @api
+     */
+    public function __construct(array $parameters, InputDefinition $definition = null)
+    {
+        $this->parameters = $parameters;
+
+        parent::__construct($definition);
+    }
+
+    /**
+     * Returns the first argument from the raw parameters (not parsed).
+     *
+     * @return string The value of the first argument or null otherwise
+     */
+    public function getFirstArgument()
+    {
+        foreach ($this->parameters as $key => $value) {
+            if ($key && '-' === $key[0]) {
+                continue;
+            }
+
+            return $value;
+        }
+    }
+
+    /**
+     * Returns true if the raw parameters (not parsed) contains a value.
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The values to look for in the raw parameters (can be an array)
+     *
+     * @return Boolean true if the value is contained in the raw parameters
+     */
+    public function hasParameterOption($values)
+    {
+        $values = (array) $values;
+
+        foreach ($this->parameters as $k => $v) {
+            if (!is_int($k)) {
+                $v = $k;
+            }
+
+            if (in_array($v, $values)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the value of a raw option (not parsed).
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+     * @param mixed $default The default value to return if no result is found
+     *
+     * @return mixed The option value
+     */
+    public function getParameterOption($values, $default = false)
+    {
+        $values = (array) $values;
+
+        foreach ($this->parameters as $k => $v) {
+            if (is_int($k) && in_array($v, $values)) {
+                return true;
+            } elseif (in_array($k, $values)) {
+                return $v;
+            }
+        }
+
+        return $default;
+    }
+
+    /**
+     * Processes command line arguments.
+     */
+    protected function parse()
+    {
+        foreach ($this->parameters as $key => $value) {
+            if ('--' === substr($key, 0, 2)) {
+                $this->addLongOption(substr($key, 2), $value);
+            } elseif ('-' === $key[0]) {
+                $this->addShortOption(substr($key, 1), $value);
+            } else {
+                $this->addArgument($key, $value);
+            }
+        }
+    }
+
+    /**
+     * Adds a short option value.
+     *
+     * @param string $shortcut The short option key
+     * @param mixed  $value    The value for the option
+     *
+     * @throws \RuntimeException When option given doesn't exist
+     */
+    private function addShortOption($shortcut, $value)
+    {
+        if (!$this->definition->hasShortcut($shortcut)) {
+            throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+        }
+
+        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+    }
+
+    /**
+     * Adds a long option value.
+     *
+     * @param string $name  The long option key
+     * @param mixed  $value The value for the option
+     *
+     * @throws \InvalidArgumentException When option given doesn't exist
+     * @throws \InvalidArgumentException When a required value is missing
+     */
+    private function addLongOption($name, $value)
+    {
+        if (!$this->definition->hasOption($name)) {
+            throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+        }
+
+        $option = $this->definition->getOption($name);
+
+        if (null === $value) {
+            if ($option->isValueRequired()) {
+                throw new \InvalidArgumentException(sprintf('The "--%s" option requires a value.', $name));
+            }
+
+            $value = $option->isValueOptional() ? $option->getDefault() : true;
+        }
+
+        $this->options[$name] = $value;
+    }
+
+    /**
+     * Adds an argument value.
+     *
+     * @param string $name  The argument name
+     * @param mixed  $value The value for the argument
+     *
+     * @throws \InvalidArgumentException When argument given doesn't exist
+     */
+    private function addArgument($name, $value)
+    {
+        if (!$this->definition->hasArgument($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+        }
+
+        $this->arguments[$name] = $value;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/Input.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/Input.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/Input.php	(revision 345)
@@ -0,0 +1,211 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Input is the base class for all concrete Input classes.
+ *
+ * Three concrete classes are provided by default:
+ *
+ *  * `ArgvInput`: The input comes from the CLI arguments (argv)
+ *  * `StringInput`: The input is provided as a string
+ *  * `ArrayInput`: The input is provided as an array
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Input implements InputInterface
+{
+    protected $definition;
+    protected $options;
+    protected $arguments;
+    protected $interactive = true;
+
+    /**
+     * Constructor.
+     *
+     * @param InputDefinition $definition A InputDefinition instance
+     */
+    public function __construct(InputDefinition $definition = null)
+    {
+        if (null === $definition) {
+            $this->definition = new InputDefinition();
+        } else {
+            $this->bind($definition);
+            $this->validate();
+        }
+    }
+
+    /**
+     * Binds the current Input instance with the given arguments and options.
+     *
+     * @param InputDefinition $definition A InputDefinition instance
+     */
+    public function bind(InputDefinition $definition)
+    {
+        $this->arguments = array();
+        $this->options = array();
+        $this->definition = $definition;
+
+        $this->parse();
+    }
+
+    /**
+     * Processes command line arguments.
+     */
+    abstract protected function parse();
+
+    /**
+     * Validates the input.
+     *
+     * @throws \RuntimeException When not enough arguments are given
+     */
+    public function validate()
+    {
+        if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {
+            throw new \RuntimeException('Not enough arguments.');
+        }
+    }
+
+    /**
+     * Checks if the input is interactive.
+     *
+     * @return Boolean Returns true if the input is interactive
+     */
+    public function isInteractive()
+    {
+        return $this->interactive;
+    }
+
+    /**
+     * Sets the input interactivity.
+     *
+     * @param Boolean $interactive If the input should be interactive
+     */
+    public function setInteractive($interactive)
+    {
+        $this->interactive = (Boolean) $interactive;
+    }
+
+    /**
+     * Returns the argument values.
+     *
+     * @return array An array of argument values
+     */
+    public function getArguments()
+    {
+        return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
+    }
+
+    /**
+     * Returns the argument value for a given argument name.
+     *
+     * @param string $name The argument name
+     *
+     * @return mixed The argument value
+     *
+     * @throws \InvalidArgumentException When argument given doesn't exist
+     */
+    public function getArgument($name)
+    {
+        if (!$this->definition->hasArgument($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+        }
+
+        return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
+    }
+
+    /**
+     * Sets an argument value by name.
+     *
+     * @param string $name  The argument name
+     * @param string $value The argument value
+     *
+     * @throws \InvalidArgumentException When argument given doesn't exist
+     */
+    public function setArgument($name, $value)
+    {
+        if (!$this->definition->hasArgument($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+        }
+
+        $this->arguments[$name] = $value;
+    }
+
+    /**
+     * Returns true if an InputArgument object exists by name or position.
+     *
+     * @param string|integer $name The InputArgument name or position
+     *
+     * @return Boolean true if the InputArgument object exists, false otherwise
+     */
+    public function hasArgument($name)
+    {
+        return $this->definition->hasArgument($name);
+    }
+
+    /**
+     * Returns the options values.
+     *
+     * @return array An array of option values
+     */
+    public function getOptions()
+    {
+        return array_merge($this->definition->getOptionDefaults(), $this->options);
+    }
+
+    /**
+     * Returns the option value for a given option name.
+     *
+     * @param string $name The option name
+     *
+     * @return mixed The option value
+     *
+     * @throws \InvalidArgumentException When option given doesn't exist
+     */
+    public function getOption($name)
+    {
+        if (!$this->definition->hasOption($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+        }
+
+        return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
+    }
+
+    /**
+     * Sets an option value by name.
+     *
+     * @param string $name  The option name
+     * @param string $value The option value
+     *
+     * @throws \InvalidArgumentException When option given doesn't exist
+     */
+    public function setOption($name, $value)
+    {
+        if (!$this->definition->hasOption($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+        }
+
+        $this->options[$name] = $value;
+    }
+
+    /**
+     * Returns true if an InputOption object exists by name.
+     *
+     * @param string $name The InputOption name
+     *
+     * @return Boolean true if the InputOption object exists, false otherwise
+     */
+    public function hasOption($name)
+    {
+        return $this->definition->hasOption($name);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputArgument.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputArgument.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputArgument.php	(revision 345)
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputArgument
+{
+    const REQUIRED = 1;
+    const OPTIONAL = 2;
+    const IS_ARRAY = 4;
+
+    private $name;
+    private $mode;
+    private $default;
+    private $description;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $name        The argument name
+     * @param integer $mode        The argument mode: self::REQUIRED or self::OPTIONAL
+     * @param string  $description A description text
+     * @param mixed   $default     The default value (for self::OPTIONAL mode only)
+     *
+     * @throws \InvalidArgumentException When argument mode is not valid
+     *
+     * @api
+     */
+    public function __construct($name, $mode = null, $description = '', $default = null)
+    {
+        if (null === $mode) {
+            $mode = self::OPTIONAL;
+        } else if (is_string($mode) || $mode > 7) {
+            throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
+        }
+
+        $this->name        = $name;
+        $this->mode        = $mode;
+        $this->description = $description;
+
+        $this->setDefault($default);
+    }
+
+    /**
+     * Returns the argument name.
+     *
+     * @return string The argument name
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Returns true if the argument is required.
+     *
+     * @return Boolean true if parameter mode is self::REQUIRED, false otherwise
+     */
+    public function isRequired()
+    {
+        return self::REQUIRED === (self::REQUIRED & $this->mode);
+    }
+
+    /**
+     * Returns true if the argument can take multiple values.
+     *
+     * @return Boolean true if mode is self::IS_ARRAY, false otherwise
+     */
+    public function isArray()
+    {
+        return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
+    }
+
+    /**
+     * Sets the default value.
+     *
+     * @param mixed $default The default value
+     *
+     * @throws \LogicException When incorrect default value is given
+     */
+    public function setDefault($default = null)
+    {
+        if (self::REQUIRED === $this->mode && null !== $default) {
+            throw new \LogicException('Cannot set a default value except for Parameter::OPTIONAL mode.');
+        }
+
+        if ($this->isArray()) {
+            if (null === $default) {
+                $default = array();
+            } else if (!is_array($default)) {
+                throw new \LogicException('A default value for an array argument must be an array.');
+            }
+        }
+
+        $this->default = $default;
+    }
+
+    /**
+     * Returns the default value.
+     *
+     * @return mixed The default value
+     */
+    public function getDefault()
+    {
+        return $this->default;
+    }
+
+    /**
+     * Returns the description text.
+     *
+     * @return string The description text
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputDefinition.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputDefinition.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputDefinition.php	(revision 345)
@@ -0,0 +1,508 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * A InputDefinition represents a set of valid command line arguments and options.
+ *
+ * Usage:
+ *
+ *     $definition = new InputDefinition(array(
+ *       new InputArgument('name', InputArgument::REQUIRED),
+ *       new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
+ *     ));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputDefinition
+{
+    private $arguments;
+    private $requiredCount;
+    private $hasAnArrayArgument = false;
+    private $hasOptional;
+    private $options;
+    private $shortcuts;
+
+    /**
+     * Constructor.
+     *
+     * @param array $definition An array of InputArgument and InputOption instance
+     *
+     * @api
+     */
+    public function __construct(array $definition = array())
+    {
+        $this->setDefinition($definition);
+    }
+
+    /**
+     * Sets the definition of the input.
+     *
+     * @param array $definition The definition array
+     *
+     * @api
+     */
+    public function setDefinition(array $definition)
+    {
+        $arguments = array();
+        $options = array();
+        foreach ($definition as $item) {
+            if ($item instanceof InputOption) {
+                $options[] = $item;
+            } else {
+                $arguments[] = $item;
+            }
+        }
+
+        $this->setArguments($arguments);
+        $this->setOptions($options);
+    }
+
+    /**
+     * Sets the InputArgument objects.
+     *
+     * @param array $arguments An array of InputArgument objects
+     *
+     * @api
+     */
+    public function setArguments($arguments = array())
+    {
+        $this->arguments          = array();
+        $this->requiredCount      = 0;
+        $this->hasOptional        = false;
+        $this->hasAnArrayArgument = false;
+        $this->addArguments($arguments);
+    }
+
+    /**
+     * Add an array of InputArgument objects.
+     *
+     * @param InputArgument[] $arguments An array of InputArgument objects
+     *
+     * @api
+     */
+    public function addArguments($arguments = array())
+    {
+        if (null !== $arguments) {
+            foreach ($arguments as $argument) {
+                $this->addArgument($argument);
+            }
+        }
+    }
+
+    /**
+     * Add an InputArgument object.
+     *
+     * @param InputArgument $argument An InputArgument object
+     *
+     * @throws \LogicException When incorrect argument is given
+     *
+     * @api
+     */
+    public function addArgument(InputArgument $argument)
+    {
+        if (isset($this->arguments[$argument->getName()])) {
+            throw new \LogicException(sprintf('An argument with name "%s" already exist.', $argument->getName()));
+        }
+
+        if ($this->hasAnArrayArgument) {
+            throw new \LogicException('Cannot add an argument after an array argument.');
+        }
+
+        if ($argument->isRequired() && $this->hasOptional) {
+            throw new \LogicException('Cannot add a required argument after an optional one.');
+        }
+
+        if ($argument->isArray()) {
+            $this->hasAnArrayArgument = true;
+        }
+
+        if ($argument->isRequired()) {
+            ++$this->requiredCount;
+        } else {
+            $this->hasOptional = true;
+        }
+
+        $this->arguments[$argument->getName()] = $argument;
+    }
+
+    /**
+     * Returns an InputArgument by name or by position.
+     *
+     * @param string|integer $name The InputArgument name or position
+     *
+     * @return InputArgument An InputArgument object
+     *
+     * @throws \InvalidArgumentException When argument given doesn't exist
+     *
+     * @api
+     */
+    public function getArgument($name)
+    {
+        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+        if (!$this->hasArgument($name)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+        }
+
+        return $arguments[$name];
+    }
+
+    /**
+     * Returns true if an InputArgument object exists by name or position.
+     *
+     * @param string|integer $name The InputArgument name or position
+     *
+     * @return Boolean true if the InputArgument object exists, false otherwise
+     *
+     * @api
+     */
+    public function hasArgument($name)
+    {
+        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+        return isset($arguments[$name]);
+    }
+
+    /**
+     * Gets the array of InputArgument objects.
+     *
+     * @return array An array of InputArgument objects
+     *
+     * @api
+     */
+    public function getArguments()
+    {
+        return $this->arguments;
+    }
+
+    /**
+     * Returns the number of InputArguments.
+     *
+     * @return integer The number of InputArguments
+     */
+    public function getArgumentCount()
+    {
+        return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
+    }
+
+    /**
+     * Returns the number of required InputArguments.
+     *
+     * @return integer The number of required InputArguments
+     */
+    public function getArgumentRequiredCount()
+    {
+        return $this->requiredCount;
+    }
+
+    /**
+     * Gets the default values.
+     *
+     * @return array An array of default values
+     */
+    public function getArgumentDefaults()
+    {
+        $values = array();
+        foreach ($this->arguments as $argument) {
+            $values[$argument->getName()] = $argument->getDefault();
+        }
+
+        return $values;
+    }
+
+    /**
+     * Sets the InputOption objects.
+     *
+     * @param array $options An array of InputOption objects
+     *
+     * @api
+     */
+    public function setOptions($options = array())
+    {
+        $this->options = array();
+        $this->shortcuts = array();
+        $this->addOptions($options);
+    }
+
+    /**
+     * Add an array of InputOption objects.
+     *
+     * @param InputOption[] $options An array of InputOption objects
+     *
+     * @api
+     */
+    public function addOptions($options = array())
+    {
+        foreach ($options as $option) {
+            $this->addOption($option);
+        }
+    }
+
+    /**
+     * Add an InputOption object.
+     *
+     * @param InputOption $option An InputOption object
+     *
+     * @throws \LogicException When option given already exist
+     *
+     * @api
+     */
+    public function addOption(InputOption $option)
+    {
+        if (isset($this->options[$option->getName()])) {
+            throw new \LogicException(sprintf('An option named "%s" already exist.', $option->getName()));
+        } else if (isset($this->shortcuts[$option->getShortcut()])) {
+            throw new \LogicException(sprintf('An option with shortcut "%s" already exist.', $option->getShortcut()));
+        }
+
+        $this->options[$option->getName()] = $option;
+        if ($option->getShortcut()) {
+            $this->shortcuts[$option->getShortcut()] = $option->getName();
+        }
+    }
+
+    /**
+     * Returns an InputOption by name.
+     *
+     * @param string $name The InputOption name
+     *
+     * @return InputOption A InputOption object
+     *
+     * @api
+     */
+    public function getOption($name)
+    {
+        if (!$this->hasOption($name)) {
+            throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+        }
+
+        return $this->options[$name];
+    }
+
+    /**
+     * Returns true if an InputOption object exists by name.
+     *
+     * @param string $name The InputOption name
+     *
+     * @return Boolean true if the InputOption object exists, false otherwise
+     *
+     * @api
+     */
+    public function hasOption($name)
+    {
+        return isset($this->options[$name]);
+    }
+
+    /**
+     * Gets the array of InputOption objects.
+     *
+     * @return array An array of InputOption objects
+     *
+     * @api
+     */
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * Returns true if an InputOption object exists by shortcut.
+     *
+     * @param string $name The InputOption shortcut
+     *
+     * @return Boolean true if the InputOption object exists, false otherwise
+     */
+    public function hasShortcut($name)
+    {
+        return isset($this->shortcuts[$name]);
+    }
+
+    /**
+     * Gets an InputOption by shortcut.
+     *
+     * @param string $shortcut the Shortcut name
+     *
+     * @return InputOption An InputOption object
+     */
+    public function getOptionForShortcut($shortcut)
+    {
+        return $this->getOption($this->shortcutToName($shortcut));
+    }
+
+    /**
+     * Gets an array of default values.
+     *
+     * @return array An array of all default values
+     */
+    public function getOptionDefaults()
+    {
+        $values = array();
+        foreach ($this->options as $option) {
+            $values[$option->getName()] = $option->getDefault();
+        }
+
+        return $values;
+    }
+
+    /**
+     * Returns the InputOption name given a shortcut.
+     *
+     * @param string $shortcut The shortcut
+     *
+     * @return string The InputOption name
+     *
+     * @throws \InvalidArgumentException When option given does not exist
+     */
+    private function shortcutToName($shortcut)
+    {
+        if (!isset($this->shortcuts[$shortcut])) {
+            throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+        }
+
+        return $this->shortcuts[$shortcut];
+    }
+
+    /**
+     * Gets the synopsis.
+     *
+     * @return string The synopsis
+     */
+    public function getSynopsis()
+    {
+        $elements = array();
+        foreach ($this->getOptions() as $option) {
+            $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
+            $elements[] = sprintf('['.($option->isValueRequired() ? '%s--%s="..."' : ($option->isValueOptional() ? '%s--%s[="..."]' : '%s--%s')).']', $shortcut, $option->getName());
+        }
+
+        foreach ($this->getArguments() as $argument) {
+            $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
+
+            if ($argument->isArray()) {
+                $elements[] = sprintf('... [%sN]', $argument->getName());
+            }
+        }
+
+        return implode(' ', $elements);
+    }
+
+    /**
+     * Returns a textual representation of the InputDefinition.
+     *
+     * @return string A string representing the InputDefinition
+     */
+    public function asText()
+    {
+        // find the largest option or argument name
+        $max = 0;
+        foreach ($this->getOptions() as $option) {
+            $max = strlen($option->getName()) + 2 > $max ? strlen($option->getName()) + 2 : $max;
+        }
+        foreach ($this->getArguments() as $argument) {
+            $max = strlen($argument->getName()) > $max ? strlen($argument->getName()) : $max;
+        }
+        ++$max;
+
+        $text = array();
+
+        if ($this->getArguments()) {
+            $text[] = '<comment>Arguments:</comment>';
+            foreach ($this->getArguments() as $argument) {
+                if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
+                    $default = sprintf('<comment> (default: %s)</comment>', is_array($argument->getDefault()) ? str_replace("\n", '', var_export($argument->getDefault(), true)): $argument->getDefault());
+                } else {
+                    $default = '';
+                }
+
+                $text[] = sprintf(" <info>%-${max}s</info> %s%s", $argument->getName(), $argument->getDescription(), $default);
+            }
+
+            $text[] = '';
+        }
+
+        if ($this->getOptions()) {
+            $text[] = '<comment>Options:</comment>';
+
+            foreach ($this->getOptions() as $option) {
+                if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
+                    $default = sprintf('<comment> (default: %s)</comment>', is_array($option->getDefault()) ? str_replace("\n", '', print_r($option->getDefault(), true)): $option->getDefault());
+                } else {
+                    $default = '';
+                }
+
+                $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
+                $text[] = sprintf(' %-'.$max.'s %s%s%s%s', '<info>--'.$option->getName().'</info>', $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '', $option->getDescription(), $default, $multiple);
+            }
+
+            $text[] = '';
+        }
+
+        return implode("\n", $text);
+    }
+
+    /**
+     * Returns an XML representation of the InputDefinition.
+     *
+     * @param Boolean $asDom Whether to return a DOM or an XML string
+     *
+     * @return string|DOMDocument An XML string representing the InputDefinition
+     */
+    public function asXml($asDom = false)
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->formatOutput = true;
+        $dom->appendChild($definitionXML = $dom->createElement('definition'));
+
+        $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+        foreach ($this->getArguments() as $argument) {
+            $argumentsXML->appendChild($argumentXML = $dom->createElement('argument'));
+            $argumentXML->setAttribute('name', $argument->getName());
+            $argumentXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+            $argumentXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+            $argumentXML->appendChild($descriptionXML = $dom->createElement('description'));
+            $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+
+            $argumentXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+            $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : ($argument->getDefault() ? array($argument->getDefault()) : array());
+            foreach ($defaults as $default) {
+                $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+                $defaultXML->appendChild($dom->createTextNode($default));
+            }
+        }
+
+        $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+        foreach ($this->getOptions() as $option) {
+            $optionsXML->appendChild($optionXML = $dom->createElement('option'));
+            $optionXML->setAttribute('name', '--'.$option->getName());
+            $optionXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
+            $optionXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+            $optionXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+            $optionXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+            $optionXML->appendChild($descriptionXML = $dom->createElement('description'));
+            $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+
+            if ($option->acceptValue()) {
+                $optionXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+                $defaults = is_array($option->getDefault()) ? $option->getDefault() : ($option->getDefault() ? array($option->getDefault()) : array());
+                foreach ($defaults as $default) {
+                    $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+                    $defaultXML->appendChild($dom->createTextNode($default));
+                }
+            }
+        }
+
+        return $asDom ? $dom : $dom->saveXml();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputInterface.php	(revision 345)
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface InputInterface
+{
+    /**
+     * Returns the first argument from the raw parameters (not parsed).
+     *
+     * @return string The value of the first argument or null otherwise
+     */
+    function getFirstArgument();
+
+    /**
+     * Returns true if the raw parameters (not parsed) contains a value.
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The values to look for in the raw parameters (can be an array)
+     *
+     * @return Boolean true if the value is contained in the raw parameters
+     */
+    function hasParameterOption($values);
+
+    /**
+     * Returns the value of a raw option (not parsed).
+     *
+     * This method is to be used to introspect the input parameters
+     * before it has been validated. It must be used carefully.
+     *
+     * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+     * @param mixed $default The default value to return if no result is found
+     *
+     * @return mixed The option value
+     */
+    function getParameterOption($values, $default = false);
+
+    /**
+     * Binds the current Input instance with the given arguments and options.
+     *
+     * @param InputDefinition $definition A InputDefinition instance
+     */
+    function bind(InputDefinition $definition);
+
+    /**
+     * Validate if arguments given are correct.
+     *
+     * Throws an exception when not enough arguments are given.
+     *
+     * @throws \RuntimeException
+     */
+    function validate();
+
+    /**
+     * Returns all the given arguments merged with the default values.
+     *
+     * @return array
+     */
+    function getArguments();
+
+    /**
+     * Get argument by name.
+     *
+     * @param string $name The name of the argument
+     * @return mixed
+     */
+    function getArgument($name);
+
+    /**
+     * @return array
+     */
+    function getOptions();
+
+    /**
+     * Get an option by name.
+     *
+     * @param string $name The name of the option
+     * @return mixed
+     */
+    function getOption($name);
+
+    /**
+     * Is this input means interactive?
+     *
+     * @return Boolean
+     */
+    function isInteractive();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputOption.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputOption.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/InputOption.php	(revision 345)
@@ -0,0 +1,182 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line option.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputOption
+{
+    const VALUE_NONE     = 1;
+    const VALUE_REQUIRED = 2;
+    const VALUE_OPTIONAL = 4;
+    const VALUE_IS_ARRAY = 8;
+
+    private $name;
+    private $shortcut;
+    private $mode;
+    private $default;
+    private $description;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $name        The option name
+     * @param string  $shortcut    The shortcut (can be null)
+     * @param integer $mode        The option mode: One of the VALUE_* constants
+     * @param string  $description A description text
+     * @param mixed   $default     The default value (must be null for self::VALUE_REQUIRED or self::VALUE_NONE)
+     *
+     * @throws \InvalidArgumentException If option mode is invalid or incompatible
+     *
+     * @api
+     */
+    public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
+    {
+        if ('--' === substr($name, 0, 2)) {
+            $name = substr($name, 2);
+        }
+
+        if (empty($shortcut)) {
+            $shortcut = null;
+        }
+
+        if (null !== $shortcut) {
+            if ('-' === $shortcut[0]) {
+                $shortcut = substr($shortcut, 1);
+            }
+        }
+
+        if (null === $mode) {
+            $mode = self::VALUE_NONE;
+        } else if (!is_int($mode) || $mode > 15) {
+            throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
+        }
+
+        $this->name        = $name;
+        $this->shortcut    = $shortcut;
+        $this->mode        = $mode;
+        $this->description = $description;
+
+        if ($this->isArray() && !$this->acceptValue()) {
+            throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
+        }
+
+        $this->setDefault($default);
+    }
+
+    /**
+     * Returns the shortcut.
+     *
+     * @return string The shortcut
+     */
+    public function getShortcut()
+    {
+        return $this->shortcut;
+    }
+
+    /**
+     * Returns the name.
+     *
+     * @return string The name
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Returns true if the option accepts a value.
+     *
+     * @return Boolean true if value mode is not self::VALUE_NONE, false otherwise
+     */
+    public function acceptValue()
+    {
+        return $this->isValueRequired() || $this->isValueOptional();
+    }
+
+    /**
+     * Returns true if the option requires a value.
+     *
+     * @return Boolean true if value mode is self::VALUE_REQUIRED, false otherwise
+     */
+    public function isValueRequired()
+    {
+        return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
+    }
+
+    /**
+     * Returns true if the option takes an optional value.
+     *
+     * @return Boolean true if value mode is self::VALUE_OPTIONAL, false otherwise
+     */
+    public function isValueOptional()
+    {
+        return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
+    }
+
+    /**
+     * Returns true if the option can take multiple values.
+     *
+     * @return Boolean true if mode is self::VALUE_IS_ARRAY, false otherwise
+     */
+    public function isArray()
+    {
+        return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
+    }
+
+    /**
+     * Sets the default value.
+     *
+     * @param mixed $default The default value
+     */
+    public function setDefault($default = null)
+    {
+        if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
+            throw new \LogicException('Cannot set a default value when using Option::VALUE_NONE mode.');
+        }
+
+        if ($this->isArray()) {
+            if (null === $default) {
+                $default = array();
+            } elseif (!is_array($default)) {
+                throw new \LogicException('A default value for an array option must be an array.');
+            }
+        }
+
+        $this->default = $this->acceptValue() ? $default : false;
+    }
+
+    /**
+     * Returns the default value.
+     *
+     * @return mixed The default value
+     */
+    public function getDefault()
+    {
+        return $this->default;
+    }
+
+    /**
+     * Returns the description text.
+     *
+     * @return string The description text
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/StringInput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/StringInput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Input/StringInput.php	(revision 345)
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * StringInput represents an input provided as a string.
+ *
+ * Usage:
+ *
+ *     $input = new StringInput('foo --bar="foobar"');
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class StringInput extends ArgvInput
+{
+    const REGEX_STRING = '([^ ]+?)(?: |(?<!\\\\)"|(?<!\\\\)\'|$)';
+    const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
+
+    /**
+     * Constructor.
+     *
+     * @param string     $input An array of parameters from the CLI (in the argv format)
+     * @param InputDefinition $definition A InputDefinition instance
+     *
+     * @api
+     */
+    public function __construct($input, InputDefinition $definition = null)
+    {
+        parent::__construct(array(), $definition);
+
+        $this->setTokens($this->tokenize($input));
+    }
+
+    /**
+     * Tokenizes a string.
+     *
+     * @param string $input The input to tokenize
+     * @throws \InvalidArgumentException When unable to parse input (should never happen)
+     */
+    private function tokenize($input)
+    {
+        $input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input);
+
+        $tokens = array();
+        $length = strlen($input);
+        $cursor = 0;
+        while ($cursor < $length) {
+            if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
+            } elseif (preg_match('/([^="\' ]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
+                $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
+            } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
+                $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
+            } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
+                $tokens[] = stripcslashes($match[1]);
+            } else {
+                // should never happen
+                // @codeCoverageIgnoreStart
+                throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
+                // @codeCoverageIgnoreEnd
+            }
+
+            $cursor += strlen($match[0]);
+        }
+
+        return $tokens;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/LICENSE
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/LICENSE	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/LICENSE	(revision 345)
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2011 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/ConsoleOutput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/ConsoleOutput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/ConsoleOutput.php	(revision 345)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * ConsoleOutput is the default class for all CLI output. It uses STDOUT.
+ *
+ * This class is a convenient wrapper around `StreamOutput`.
+ *
+ *     $output = new ConsoleOutput();
+ *
+ * This is equivalent to:
+ *
+ *     $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ConsoleOutput extends StreamOutput
+{
+    /**
+     * Constructor.
+     *
+     * @param integer         $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
+     *                                   self::VERBOSITY_VERBOSE)
+     * @param Boolean         $decorated Whether to decorate messages or not (null for auto-guessing)
+     * @param OutputFormatter $formatter Output formatter instance
+     *
+     * @api
+     */
+    public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatter $formatter = null)
+    {
+        parent::__construct(fopen('php://stdout', 'w'), $verbosity, $decorated, $formatter);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/NullOutput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/NullOutput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/NullOutput.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * NullOutput suppresses all output.
+ *
+ *     $output = new NullOutput();
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class NullOutput extends Output
+{
+    /**
+     * Writes a message to the output.
+     *
+     * @param string $message A message to write to the output
+     * @param Boolean $newline Whether to add a newline or not
+     */
+    public function doWrite($message, $newline)
+    {
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/Output.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/Output.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/Output.php	(revision 345)
@@ -0,0 +1,184 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * Base class for output classes.
+ *
+ * There is three level of verbosity:
+ *
+ *  * normal: no option passed (normal output - information)
+ *  * verbose: -v (more output - debug)
+ *  * quiet: -q (no output)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+abstract class Output implements OutputInterface
+{
+    private $verbosity;
+    private $formatter;
+
+    /**
+     * Constructor.
+     *
+     * @param integer                  $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE)
+     * @param Boolean                  $decorated Whether to decorate messages or not (null for auto-guessing)
+     * @param OutputFormatterInterface $formatter Output formatter instance
+     *
+     * @api
+     */
+    public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+    {
+        if (null === $formatter) {
+            $formatter = new OutputFormatter();
+        }
+
+        $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
+        $this->formatter = $formatter;
+        $this->formatter->setDecorated((Boolean) $decorated);
+    }
+
+    /**
+     * Sets output formatter.
+     *
+     * @param OutputFormatterInterface $formatter
+     *
+     * @api
+     */
+    public function setFormatter(OutputFormatterInterface $formatter)
+    {
+        $this->formatter = $formatter;
+    }
+
+    /**
+     * Returns current output formatter instance.
+     *
+     * @return  OutputFormatterInterface
+     *
+     * @api
+     */
+    public function getFormatter()
+    {
+        return $this->formatter;
+    }
+
+    /**
+     * Sets the decorated flag.
+     *
+     * @param Boolean $decorated Whether to decorated the messages or not
+     *
+     * @api
+     */
+    public function setDecorated($decorated)
+    {
+        $this->formatter->setDecorated((Boolean) $decorated);
+    }
+
+    /**
+     * Gets the decorated flag.
+     *
+     * @return Boolean true if the output will decorate messages, false otherwise
+     *
+     * @api
+     */
+    public function isDecorated()
+    {
+        return $this->formatter->isDecorated();
+    }
+
+    /**
+     * Sets the verbosity of the output.
+     *
+     * @param integer $level The level of verbosity
+     *
+     * @api
+     */
+    public function setVerbosity($level)
+    {
+        $this->verbosity = (int) $level;
+    }
+
+    /**
+     * Gets the current verbosity of the output.
+     *
+     * @return integer The current level of verbosity
+     *
+     * @api
+     */
+    public function getVerbosity()
+    {
+        return $this->verbosity;
+    }
+
+    /**
+     * Writes a message to the output and adds a newline at the end.
+     *
+     * @param string|array $messages The message as an array of lines of a single string
+     * @param integer      $type     The type of output
+     *
+     * @api
+     */
+    public function writeln($messages, $type = 0)
+    {
+        $this->write($messages, true, $type);
+    }
+
+    /**
+     * Writes a message to the output.
+     *
+     * @param string|array $messages The message as an array of lines of a single string
+     * @param Boolean      $newline  Whether to add a newline or not
+     * @param integer      $type     The type of output
+     *
+     * @throws \InvalidArgumentException When unknown output type is given
+     *
+     * @api
+     */
+    public function write($messages, $newline = false, $type = 0)
+    {
+        if (self::VERBOSITY_QUIET === $this->verbosity) {
+            return;
+        }
+
+        $messages = (array) $messages;
+
+        foreach ($messages as $message) {
+            switch ($type) {
+                case OutputInterface::OUTPUT_NORMAL:
+                    $message = $this->formatter->format($message);
+                    break;
+                case OutputInterface::OUTPUT_RAW:
+                    break;
+                case OutputInterface::OUTPUT_PLAIN:
+                    $message = strip_tags($this->formatter->format($message));
+                    break;
+                default:
+                    throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));
+            }
+
+            $this->doWrite($message, $newline);
+        }
+    }
+
+    /**
+     * Writes a message to the output.
+     *
+     * @param string  $message A message to write to the output
+     * @param Boolean $newline Whether to add a newline or not
+     */
+    abstract public function doWrite($message, $newline);
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/OutputInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/OutputInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/OutputInterface.php	(revision 345)
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * OutputInterface is the interface implemented by all Output classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface OutputInterface
+{
+    const VERBOSITY_QUIET   = 0;
+    const VERBOSITY_NORMAL  = 1;
+    const VERBOSITY_VERBOSE = 2;
+
+    const OUTPUT_NORMAL = 0;
+    const OUTPUT_RAW = 1;
+    const OUTPUT_PLAIN = 2;
+
+    /**
+     * Writes a message to the output.
+     *
+     * @param string|array $messages The message as an array of lines of a single string
+     * @param Boolean      $newline  Whether to add a newline or not
+     * @param integer      $type     The type of output
+     *
+     * @throws \InvalidArgumentException When unknown output type is given
+     *
+     * @api
+     */
+    function write($messages, $newline = false, $type = 0);
+
+    /**
+     * Writes a message to the output and adds a newline at the end.
+     *
+     * @param string|array $messages The message as an array of lines of a single string
+     * @param integer      $type     The type of output
+     *
+     * @api
+     */
+    function writeln($messages, $type = 0);
+
+    /**
+     * Sets the verbosity of the output.
+     *
+     * @param integer $level The level of verbosity
+     *
+     * @api
+     */
+    function setVerbosity($level);
+
+    /**
+     * Gets the current verbosity of the output.
+     *
+     * @return integer The current level of verbosity
+     */
+    function getVerbosity();
+
+    /**
+     * Sets the decorated flag.
+     *
+     * @param Boolean $decorated Whether to decorated the messages or not
+     *
+     * @api
+     */
+    function setDecorated($decorated);
+
+    /**
+     * Gets the decorated flag.
+     *
+     * @return Boolean true if the output will decorate messages, false otherwise
+     *
+     * @api
+     */
+    function isDecorated();
+
+    /**
+     * Sets output formatter.
+     *
+     * @param OutputFormatterInterface $formatter
+     *
+     * @api
+     */
+    function setFormatter(OutputFormatterInterface $formatter);
+
+    /**
+     * Returns current output formatter instance.
+     *
+     * @return  OutputFormatterInterface
+     *
+     * @api
+     */
+    function getFormatter();
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/StreamOutput.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/StreamOutput.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Output/StreamOutput.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * StreamOutput writes the output to a given stream.
+ *
+ * Usage:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * As `StreamOutput` can use any stream, you can also use a file:
+ *
+ * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class StreamOutput extends Output
+{
+    private $stream;
+
+    /**
+     * Constructor.
+     *
+     * @param mixed           $stream    A stream resource
+     * @param integer         $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
+     *                                   self::VERBOSITY_VERBOSE)
+     * @param Boolean         $decorated Whether to decorate messages or not (null for auto-guessing)
+     * @param OutputFormatter $formatter Output formatter instance
+     *
+     * @throws \InvalidArgumentException When first argument is not a real stream
+     *
+     * @api
+     */
+    public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatter $formatter = null)
+    {
+        if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+            throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
+        }
+
+        $this->stream = $stream;
+
+        if (null === $decorated) {
+            $decorated = $this->hasColorSupport($decorated);
+        }
+
+        parent::__construct($verbosity, $decorated, $formatter);
+    }
+
+    /**
+     * Gets the stream attached to this StreamOutput instance.
+     *
+     * @return resource A stream resource
+     */
+    public function getStream()
+    {
+        return $this->stream;
+    }
+
+    /**
+     * Writes a message to the output.
+     *
+     * @param string  $message A message to write to the output
+     * @param Boolean $newline Whether to add a newline or not
+     *
+     * @throws \RuntimeException When unable to write output (should never happen)
+     */
+    public function doWrite($message, $newline)
+    {
+        if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
+            // @codeCoverageIgnoreStart
+            // should never happen
+            throw new \RuntimeException('Unable to write output.');
+            // @codeCoverageIgnoreEnd
+        }
+
+        fflush($this->stream);
+    }
+
+    /**
+     * Returns true if the stream supports colorization.
+     *
+     * Colorization is disabled if not supported by the stream:
+     *
+     *  -  windows without ansicon
+     *  -  non tty consoles
+     *
+     * @return Boolean true if the stream supports colorization, false otherwise
+     */
+    protected function hasColorSupport()
+    {
+        // @codeCoverageIgnoreStart
+        if (DIRECTORY_SEPARATOR == '\\') {
+            return false !== getenv('ANSICON');
+        }
+
+        return function_exists('posix_isatty') && @posix_isatty($this->stream);
+        // @codeCoverageIgnoreEnd
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Shell.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Shell.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Shell.php	(revision 345)
@@ -0,0 +1,136 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+
+/**
+ * A Shell wraps an Application to add shell capabilities to it.
+ *
+ * This class only works with a PHP compiled with readline support
+ * (either --with-readline or --with-libedit)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Shell
+{
+    private $application;
+    private $history;
+    private $output;
+
+    /**
+     * Constructor.
+     *
+     * If there is no readline support for the current PHP executable
+     * a \RuntimeException exception is thrown.
+     *
+     * @param Application $application An application instance
+     *
+     * @throws \RuntimeException When Readline extension is not enabled
+     */
+    public function __construct(Application $application)
+    {
+        if (!function_exists('readline')) {
+            throw new \RuntimeException('Unable to start the shell as the Readline extension is not enabled.');
+        }
+
+        $this->application = $application;
+        $this->history = getenv('HOME').'/.history_'.$application->getName();
+        $this->output = new ConsoleOutput();
+    }
+
+    /**
+     * Runs the shell.
+     */
+    public function run()
+    {
+        $this->application->setAutoExit(false);
+        $this->application->setCatchExceptions(true);
+
+        readline_read_history($this->history);
+        readline_completion_function(array($this, 'autocompleter'));
+
+        $this->output->writeln($this->getHeader());
+        while (true) {
+            $command = readline($this->application->getName().' > ');
+
+            if (false === $command) {
+                $this->output->writeln("\n");
+
+                break;
+            }
+
+            readline_add_history($command);
+            readline_write_history($this->history);
+
+            if (0 !== $ret = $this->application->run(new StringInput($command), $this->output)) {
+                $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
+            }
+        }
+    }
+
+    /**
+     * Tries to return autocompletion for the current entered text.
+     *
+     * @param string  $text     The last segment of the entered text
+     * @param integer $position The current position
+     */
+    private function autocompleter($text, $position)
+    {
+        $info = readline_info();
+        $text = substr($info['line_buffer'], 0, $info['end']);
+
+        if ($info['point'] !== $info['end']) {
+            return true;
+        }
+
+        // task name?
+        if (false === strpos($text, ' ') || !$text) {
+            return array_keys($this->application->all());
+        }
+
+        // options and arguments?
+        try {
+            $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
+        } catch (\Exception $e) {
+            return true;
+        }
+
+        $list = array('--help');
+        foreach ($command->getDefinition()->getOptions() as $option) {
+            $list[] = '--'.$option->getName();
+        }
+
+        return $list;
+    }
+
+    /**
+     * Returns the shell header.
+     *
+     * @return string The header string
+     */
+    protected function getHeader()
+    {
+        return <<<EOF
+
+Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
+
+At the prompt, type <comment>help</comment> for some help,
+or <comment>list</comment> to get a list available commands.
+
+To exit the shell, type <comment>^D</comment>.
+
+EOF;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/ApplicationTester.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/ApplicationTester.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/ApplicationTester.php	(revision 345)
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ApplicationTester
+{
+    private $application;
+    private $input;
+    private $output;
+
+    /**
+     * Constructor.
+     *
+     * @param Application $application An Application instance to test.
+     */
+    public function __construct(Application $application)
+    {
+        $this->application = $application;
+    }
+
+    /**
+     * Executes the application.
+     *
+     * Available options:
+     *
+     *  * interactive: Sets the input interactive flag
+     *  * decorated:   Sets the output decorated flag
+     *  * verbosity:   Sets the output verbosity flag
+     *
+     * @param array $input   An array of arguments and options
+     * @param array $options An array of options
+     *
+     * @return integer The command exit code
+     */
+    public function run(array $input, $options = array())
+    {
+        $this->inputs = new ArrayInput($input);
+        if (isset($options['interactive'])) {
+            $this->inputs->setInteractive($options['interactive']);
+        }
+
+        $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+        if (isset($options['decorated'])) {
+            $this->output->setDecorated($options['decorated']);
+        }
+        if (isset($options['verbosity'])) {
+            $this->output->setVerbosity($options['verbosity']);
+        }
+
+        return $this->application->run($this->inputs, $this->output);
+    }
+
+    /**
+     * Gets the display returned by the last execution of the application.
+     *
+     * @return string The display
+     */
+    public function getDisplay()
+    {
+        rewind($this->output->getStream());
+
+        return stream_get_contents($this->output->getStream());
+    }
+
+    /**
+     * Gets the input instance used by the last execution of the application.
+     *
+     * @return InputInterface The current input instance
+     */
+    public function getInput()
+    {
+        return $this->inputs;
+    }
+
+    /**
+     * Gets the output instance used by the last execution of the application.
+     *
+     * @return OutputInterface The current output instance
+     */
+    public function getOutput()
+    {
+        return $this->output;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/CommandTester.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/CommandTester.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Console/Tester/CommandTester.php	(revision 345)
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CommandTester
+{
+    private $command;
+    private $input;
+    private $output;
+
+    /**
+     * Constructor.
+     *
+     * @param Command $command A Command instance to test.
+     */
+    public function __construct(Command $command)
+    {
+        $this->command = $command;
+    }
+
+    /**
+     * Executes the command.
+     *
+     * Available options:
+     *
+     *  * interactive: Sets the input interactive flag
+     *  * decorated:   Sets the output decorated flag
+     *  * verbosity:   Sets the output verbosity flag
+     *
+     * @param array $input   An array of arguments and options
+     * @param array $options An array of options
+     *
+     * @return integer The command exit code
+     */
+    public function execute(array $input, array $options = array())
+    {
+        $this->inputs = new ArrayInput($input);
+        if (isset($options['interactive'])) {
+            $this->inputs->setInteractive($options['interactive']);
+        }
+
+        $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+        if (isset($options['decorated'])) {
+            $this->output->setDecorated($options['decorated']);
+        }
+        if (isset($options['verbosity'])) {
+            $this->output->setVerbosity($options['verbosity']);
+        }
+
+        return $this->command->run($this->inputs, $this->output);
+    }
+
+    /**
+     * Gets the display returned by the last execution of the command.
+     *
+     * @return string The display
+     */
+    public function getDisplay()
+    {
+        rewind($this->output->getStream());
+
+        return stream_get_contents($this->output->getStream());
+    }
+
+    /**
+     * Gets the input instance used by the last execution of the command.
+     *
+     * @return InputInterface The current input instance
+     */
+    public function getInput()
+    {
+        return $this->inputs;
+    }
+
+    /**
+     * Gets the output instance used by the last execution of the command.
+     *
+     * @return OutputInterface The current output instance
+     */
+    public function getOutput()
+    {
+        return $this->output;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Dumper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Dumper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Dumper.php	(revision 345)
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Dumper dumps PHP variables to YAML strings.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Dumper
+{
+    /**
+     * Dumps a PHP value to YAML.
+     *
+     * @param  mixed   $input  The PHP value
+     * @param  integer $inline The level where you switch to inline YAML
+     * @param  integer $indent The level of indentation (used internally)
+     *
+     * @return string  The YAML representation of the PHP value
+     */
+    public function dump($input, $inline = 0, $indent = 0)
+    {
+        $output = '';
+        $prefix = $indent ? str_repeat(' ', $indent) : '';
+
+        if ($inline <= 0 || !is_array($input) || empty($input)) {
+            $output .= $prefix.Inline::dump($input);
+        } else {
+            $isAHash = array_keys($input) !== range(0, count($input) - 1);
+
+            foreach ($input as $key => $value) {
+                $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
+
+                $output .= sprintf('%s%s%s%s',
+                    $prefix,
+                    $isAHash ? Inline::dump($key).':' : '-',
+                    $willBeInlined ? ' ' : "\n",
+                    $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2)
+                ).($willBeInlined ? "\n" : '');
+            }
+        }
+
+        return $output;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Escaper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Escaper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Escaper.php	(revision 345)
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Escaper encapsulates escaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Escaper
+{
+    // Characters that would cause a dumped string to require double quoting.
+    const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
+
+    // Mapping arrays for escaping a double quoted string. The backslash is
+    // first to ensure proper escaping because str_replace operates iteratively
+    // on the input arrays. This ordering of the characters avoids the use of strtr,
+    // which performs more slowly.
+    static private $escapees = array('\\\\', '\\"',
+                                     "\x00",  "\x01",  "\x02",  "\x03",  "\x04",  "\x05",  "\x06",  "\x07",
+                                     "\x08",  "\x09",  "\x0a",  "\x0b",  "\x0c",  "\x0d",  "\x0e",  "\x0f",
+                                     "\x10",  "\x11",  "\x12",  "\x13",  "\x14",  "\x15",  "\x16",  "\x17",
+                                     "\x18",  "\x19",  "\x1a",  "\x1b",  "\x1c",  "\x1d",  "\x1e",  "\x1f",
+                                     "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
+    static private $escaped  = array('\\"', '\\\\',
+                                     "\\0",   "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
+                                     "\\b",   "\\t",   "\\n",   "\\v",   "\\f",   "\\r",   "\\x0e", "\\x0f",
+                                     "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
+                                     "\\x18", "\\x19", "\\x1a", "\\e",   "\\x1c", "\\x1d", "\\x1e", "\\x1f",
+                                     "\\N", "\\_", "\\L", "\\P");
+
+    /**
+     * Determines if a PHP value would require double quoting in YAML.
+     *
+     * @param string $value A PHP value
+     *
+     * @return Boolean True if the value would require double quotes.
+     */
+    static public function requiresDoubleQuoting($value)
+    {
+        return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
+    }
+
+    /**
+     * Escapes and surrounds a PHP value with double quotes.
+     *
+     * @param string $value A PHP value
+     *
+     * @return string The quoted, escaped string
+     */
+    static public function escapeWithDoubleQuotes($value)
+    {
+        return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
+    }
+
+    /**
+     * Determines if a PHP value would require single quoting in YAML.
+     *
+     * @param string $value A PHP value
+     *
+     * @return Boolean True if the value would require single quotes.
+     */
+    static public function requiresSingleQuoting($value)
+    {
+        return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value);
+    }
+
+    /**
+     * Escapes and surrounds a PHP value with single quotes.
+     *
+     * @param string $value A PHP value
+     *
+     * @return string The quoted, escaped string
+     */
+    static public function escapeWithSingleQuotes($value)
+    {
+        return sprintf("'%s'", str_replace('\'', '\'\'', $value));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/DumpException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/DumpException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/DumpException.php	(revision 345)
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during dumping.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class DumpException extends \RuntimeException implements ExceptionInterface
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ExceptionInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ExceptionInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ExceptionInterface.php	(revision 345)
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ParseException.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ParseException.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Exception/ParseException.php	(revision 345)
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ParseException extends \RuntimeException implements ExceptionInterface
+{
+    private $parsedFile;
+    private $parsedLine;
+    private $snippet;
+    private $rawMessage;
+
+    /**
+     * Constructor.
+     *
+     * @param string    $message  The error message
+     * @param integer   $lineno   The line where the error occurred
+     * @param integer   $snippet  The snippet of code near the problem
+     * @param string    $filename The file name where the error occurred
+     * @param Exception $previous The previous exception
+     */
+    public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, Exception $previous = null)
+    {
+        $this->parsedFile = $parsedFile;
+        $this->parsedLine = $parsedLine;
+        $this->snippet = $snippet;
+        $this->rawMessage = $message;
+
+        $this->updateRepr();
+
+        parent::__construct($this->message, 0, $previous);
+    }
+
+    /**
+     * Gets the snippet of code near the error.
+     *
+     * @return string The snippet of code
+     */
+    public function getSnippet()
+    {
+        return $this->snippet;
+    }
+
+    /**
+     * Sets the snippet of code near the error.
+     *
+     * @param string $parsedFile The filename
+     */
+    public function setSnippet($snippet)
+    {
+        $this->snippet = $snippet;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * Gets the filename where the error occurred.
+     *
+     * This method returns null if a string is parsed.
+     *
+     * @return string The filename
+     */
+    public function getParsedFile()
+    {
+        return $this->parsedFile;
+    }
+
+    /**
+     * Sets the filename where the error occurred.
+     *
+     * @param string $parsedFile The filename
+     */
+    public function setParsedFile($parsedFile)
+    {
+        $this->parsedFile = $parsedFile;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * Gets the line where the error occurred.
+     *
+     * @return integer The file line
+     */
+    public function getParsedLine()
+    {
+        return $this->parsedLine;
+    }
+
+    /**
+     * Sets the line where the error occurred.
+     *
+     * @param integer $parsedLine The file line
+     */
+    public function setParsedLine($parsedLine)
+    {
+        $this->parsedLine = $parsedLine;
+
+        $this->updateRepr();
+    }
+
+    private function updateRepr()
+    {
+        $this->message = $this->rawMessage;
+
+        $dot = false;
+        if ('.' === substr($this->message, -1)) {
+            $this->message = substr($this->message, 0, -1);
+            $dot = true;
+        }
+
+        if (null !== $this->parsedFile) {
+            $this->message .= sprintf(' in %s', json_encode($this->parsedFile));
+        }
+
+        if ($this->parsedLine >= 0) {
+            $this->message .= sprintf(' at line %d', $this->parsedLine);
+        }
+
+        if ($this->snippet) {
+            $this->message .= sprintf(' (near "%s")', $this->snippet);
+        }
+
+        if ($dot) {
+            $this->message .= '.';
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Inline.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Inline.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Inline.php	(revision 345)
@@ -0,0 +1,396 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Exception\DumpException;
+
+/**
+ * Inline implements a YAML parser/dumper for the YAML inline syntax.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Inline
+{
+    const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
+
+    /**
+     * Converts a YAML string to a PHP array.
+     *
+     * @param string $value A YAML string
+     *
+     * @return array A PHP array representing the YAML string
+     */
+    static public function parse($value)
+    {
+        $value = trim($value);
+
+        if (0 == strlen($value)) {
+            return '';
+        }
+
+        if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+            $mbEncoding = mb_internal_encoding();
+            mb_internal_encoding('ASCII');
+        }
+
+        switch ($value[0]) {
+            case '[':
+                $result = self::parseSequence($value);
+                break;
+            case '{':
+                $result = self::parseMapping($value);
+                break;
+            default:
+                $result = self::parseScalar($value);
+        }
+
+        if (isset($mbEncoding)) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Dumps a given PHP variable to a YAML string.
+     *
+     * @param mixed $value The PHP variable to convert
+     *
+     * @return string The YAML string representing the PHP array
+     *
+     * @throws DumpException When trying to dump PHP resource
+     */
+    static public function dump($value)
+    {
+        switch (true) {
+            case is_resource($value):
+                throw new DumpException('Unable to dump PHP resources in a YAML file.');
+            case is_object($value):
+                return '!!php/object:'.serialize($value);
+            case is_array($value):
+                return self::dumpArray($value);
+            case null === $value:
+                return 'null';
+            case true === $value:
+                return 'true';
+            case false === $value:
+                return 'false';
+            case ctype_digit($value):
+                return is_string($value) ? "'$value'" : (int) $value;
+            case is_numeric($value):
+                return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value);
+            case Escaper::requiresDoubleQuoting($value):
+                return Escaper::escapeWithDoubleQuotes($value);
+            case Escaper::requiresSingleQuoting($value):
+                return Escaper::escapeWithSingleQuotes($value);
+            case '' == $value:
+                return "''";
+            case preg_match(self::getTimestampRegex(), $value):
+            case in_array(strtolower($value), array('null', '~', 'true', 'false')):
+                return "'$value'";
+            default:
+                return $value;
+        }
+    }
+
+    /**
+     * Dumps a PHP array to a YAML string.
+     *
+     * @param array $value The PHP array to dump
+     *
+     * @return string The YAML string representing the PHP array
+     */
+    static private function dumpArray($value)
+    {
+        // array
+        $keys = array_keys($value);
+        if ((1 == count($keys) && '0' == $keys[0])
+            || (count($keys) > 1 && array_reduce($keys, function ($v, $w) { return (integer) $v + $w; }, 0) == count($keys) * (count($keys) - 1) / 2)
+        ) {
+            $output = array();
+            foreach ($value as $val) {
+                $output[] = self::dump($val);
+            }
+
+            return sprintf('[%s]', implode(', ', $output));
+        }
+
+        // mapping
+        $output = array();
+        foreach ($value as $key => $val) {
+            $output[] = sprintf('%s: %s', self::dump($key), self::dump($val));
+        }
+
+        return sprintf('{ %s }', implode(', ', $output));
+    }
+
+    /**
+     * Parses a scalar to a YAML string.
+     *
+     * @param scalar  $scalar
+     * @param string  $delimiters
+     * @param array   $stringDelimiters
+     * @param integer &$i
+     * @param Boolean $evaluate
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
+    {
+        if (in_array($scalar[$i], $stringDelimiters)) {
+            // quoted scalar
+            $output = self::parseQuotedScalar($scalar, $i);
+        } else {
+            // "normal" string
+            if (!$delimiters) {
+                $output = substr($scalar, $i);
+                $i += strlen($output);
+
+                // remove comments
+                if (false !== $strpos = strpos($output, ' #')) {
+                    $output = rtrim(substr($output, 0, $strpos));
+                }
+            } else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
+                $output = $match[1];
+                $i += strlen($output);
+            } else {
+                throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
+            }
+
+            $output = $evaluate ? self::evaluateScalar($output) : $output;
+        }
+
+        return $output;
+    }
+
+    /**
+     * Parses a quoted scalar to YAML.
+     *
+     * @param string  $scalar
+     * @param integer $i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseQuotedScalar($scalar, &$i)
+    {
+        if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
+            throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
+        }
+
+        $output = substr($match[0], 1, strlen($match[0]) - 2);
+
+        $unescaper = new Unescaper();
+        if ('"' == $scalar[$i]) {
+            $output = $unescaper->unescapeDoubleQuotedString($output);
+        } else {
+            $output = $unescaper->unescapeSingleQuotedString($output);
+        }
+
+        $i += strlen($match[0]);
+
+        return $output;
+    }
+
+    /**
+     * Parses a sequence to a YAML string.
+     *
+     * @param string  $sequence
+     * @param integer $i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseSequence($sequence, &$i = 0)
+    {
+        $output = array();
+        $len = strlen($sequence);
+        $i += 1;
+
+        // [foo, bar, ...]
+        while ($i < $len) {
+            switch ($sequence[$i]) {
+                case '[':
+                    // nested sequence
+                    $output[] = self::parseSequence($sequence, $i);
+                    break;
+                case '{':
+                    // nested mapping
+                    $output[] = self::parseMapping($sequence, $i);
+                    break;
+                case ']':
+                    return $output;
+                case ',':
+                case ' ':
+                    break;
+                default:
+                    $isQuoted = in_array($sequence[$i], array('"', "'"));
+                    $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
+
+                    if (!$isQuoted && false !== strpos($value, ': ')) {
+                        // embedded mapping?
+                        try {
+                            $value = self::parseMapping('{'.$value.'}');
+                        } catch (\InvalidArgumentException $e) {
+                            // no, it's not
+                        }
+                    }
+
+                    $output[] = $value;
+
+                    --$i;
+            }
+
+            ++$i;
+        }
+
+        throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
+    }
+
+    /**
+     * Parses a mapping to a YAML string.
+     *
+     * @param string  $mapping
+     * @param integer $i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseMapping($mapping, &$i = 0)
+    {
+        $output = array();
+        $len = strlen($mapping);
+        $i += 1;
+
+        // {foo: bar, bar:foo, ...}
+        while ($i < $len) {
+            switch ($mapping[$i]) {
+                case ' ':
+                case ',':
+                    ++$i;
+                    continue 2;
+                case '}':
+                    return $output;
+            }
+
+            // key
+            $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
+
+            // value
+            $done = false;
+            while ($i < $len) {
+                switch ($mapping[$i]) {
+                    case '[':
+                        // nested sequence
+                        $output[$key] = self::parseSequence($mapping, $i);
+                        $done = true;
+                        break;
+                    case '{':
+                        // nested mapping
+                        $output[$key] = self::parseMapping($mapping, $i);
+                        $done = true;
+                        break;
+                    case ':':
+                    case ' ':
+                        break;
+                    default:
+                        $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
+                        $done = true;
+                        --$i;
+                }
+
+                ++$i;
+
+                if ($done) {
+                    continue 2;
+                }
+            }
+        }
+
+        throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
+    }
+
+    /**
+     * Evaluates scalars and replaces magic values.
+     *
+     * @param string $scalar
+     *
+     * @return string A YAML string
+     */
+    static private function evaluateScalar($scalar)
+    {
+        $scalar = trim($scalar);
+
+        switch (true) {
+            case 'null' == strtolower($scalar):
+            case '' == $scalar:
+            case '~' == $scalar:
+                return null;
+            case 0 === strpos($scalar, '!str'):
+                return (string) substr($scalar, 5);
+            case 0 === strpos($scalar, '! '):
+                return intval(self::parseScalar(substr($scalar, 2)));
+            case 0 === strpos($scalar, '!!php/object:'):
+                return unserialize(substr($scalar, 13));
+            case ctype_digit($scalar):
+                $raw = $scalar;
+                $cast = intval($scalar);
+
+                return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
+            case 'true' === strtolower($scalar):
+                return true;
+            case 'false' === strtolower($scalar):
+                return false;
+            case is_numeric($scalar):
+                return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
+            case 0 == strcasecmp($scalar, '.inf'):
+            case 0 == strcasecmp($scalar, '.NaN'):
+                return -log(0);
+            case 0 == strcasecmp($scalar, '-.inf'):
+                return log(0);
+            case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
+                return floatval(str_replace(',', '', $scalar));
+            case preg_match(self::getTimestampRegex(), $scalar):
+                return strtotime($scalar);
+            default:
+                return (string) $scalar;
+        }
+    }
+
+    /**
+     * Gets a regex that matches an unix timestamp
+     *
+     * @return string The regular expression
+     */
+    static private function getTimestampRegex()
+    {
+        return <<<EOF
+        ~^
+        (?P<year>[0-9][0-9][0-9][0-9])
+        -(?P<month>[0-9][0-9]?)
+        -(?P<day>[0-9][0-9]?)
+        (?:(?:[Tt]|[ \t]+)
+        (?P<hour>[0-9][0-9]?)
+        :(?P<minute>[0-9][0-9])
+        :(?P<second>[0-9][0-9])
+        (?:\.(?P<fraction>[0-9]*))?
+        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
+        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
+        $~x
+EOF;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/LICENSE
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/LICENSE	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/LICENSE	(revision 345)
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2011 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Parser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Parser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Parser.php	(revision 345)
@@ -0,0 +1,556 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Parser parses YAML strings to convert them to PHP arrays.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Parser
+{
+    private $offset         = 0;
+    private $lines          = array();
+    private $currentLineNb  = -1;
+    private $currentLine    = '';
+    private $refs           = array();
+
+    /**
+     * Constructor
+     *
+     * @param integer $offset The offset of YAML document (used for line numbers in error messages)
+     */
+    public function __construct($offset = 0)
+    {
+        $this->offset = $offset;
+    }
+
+    /**
+     * Parses a YAML string to a PHP value.
+     *
+     * @param  string $value A YAML string
+     *
+     * @return mixed  A PHP value
+     *
+     * @throws ParseException If the YAML is not valid
+     */
+    public function parse($value)
+    {
+        $this->currentLineNb = -1;
+        $this->currentLine = '';
+        $this->lines = explode("\n", $this->cleanup($value));
+
+        if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) {
+            throw new ParseException('The YAML value does not appear to be valid UTF-8.');
+        }
+
+        if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+            $mbEncoding = mb_internal_encoding();
+            mb_internal_encoding('UTF-8');
+        }
+
+        $data = array();
+        while ($this->moveToNextLine()) {
+            if ($this->isCurrentLineEmpty()) {
+                continue;
+            }
+
+            // tab?
+            if (preg_match('#^\t+#', $this->currentLine)) {
+                throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+
+            $isRef = $isInPlace = $isProcessed = false;
+            if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
+                if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+                    $isRef = $matches['ref'];
+                    $values['value'] = $matches['value'];
+                }
+
+                // array
+                if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+                    $c = $this->getRealCurrentLineNb() + 1;
+                    $parser = new Parser($c);
+                    $parser->refs =& $this->refs;
+                    $data[] = $parser->parse($this->getNextEmbedBlock());
+                } else {
+                    if (isset($values['leadspaces'])
+                        && ' ' == $values['leadspaces']
+                        && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
+                    ) {
+                        // this is a compact notation element, add to next block and parse
+                        $c = $this->getRealCurrentLineNb();
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+
+                        $block = $values['value'];
+                        if (!$this->isNextLineIndented()) {
+                            $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2);
+                        }
+
+                        $data[] = $parser->parse($block);
+                    } else {
+                        $data[] = $this->parseValue($values['value']);
+                    }
+                }
+            } else if (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
+                try {
+                    $key = Inline::parseScalar($values['key']);
+                } catch (ParseException $e) {
+                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+                    $e->setSnippet($this->currentLine);
+
+                    throw $e;
+                }
+
+                if ('<<' === $key) {
+                    if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) {
+                        $isInPlace = substr($values['value'], 1);
+                        if (!array_key_exists($isInPlace, $this->refs)) {
+                            throw new ParseException(sprintf('Reference "%s" does not exist.', $isInPlace), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+                        }
+                    } else {
+                        if (isset($values['value']) && $values['value'] !== '') {
+                            $value = $values['value'];
+                        } else {
+                            $value = $this->getNextEmbedBlock();
+                        }
+                        $c = $this->getRealCurrentLineNb() + 1;
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+                        $parsed = $parser->parse($value);
+
+                        $merged = array();
+                        if (!is_array($parsed)) {
+                            throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+                        } else if (isset($parsed[0])) {
+                            // Numeric array, merge individual elements
+                            foreach (array_reverse($parsed) as $parsedItem) {
+                                if (!is_array($parsedItem)) {
+                                    throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
+                                }
+                                $merged = array_merge($parsedItem, $merged);
+                            }
+                        } else {
+                            // Associative array, merge
+                            $merged = array_merge($merged, $parsed);
+                        }
+
+                        $isProcessed = $merged;
+                    }
+                } else if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+                    $isRef = $matches['ref'];
+                    $values['value'] = $matches['value'];
+                }
+
+                if ($isProcessed) {
+                    // Merge keys
+                    $data = $isProcessed;
+                // hash
+                } else if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+                    // if next line is less indented or equal, then it means that the current value is null
+                    if ($this->isNextLineIndented()) {
+                        $data[$key] = null;
+                    } else {
+                        $c = $this->getRealCurrentLineNb() + 1;
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+                        $data[$key] = $parser->parse($this->getNextEmbedBlock());
+                    }
+                } else {
+                    if ($isInPlace) {
+                        $data = $this->refs[$isInPlace];
+                    } else {
+                        $data[$key] = $this->parseValue($values['value']);
+                    }
+                }
+            } else {
+                // 1-liner followed by newline
+                if (2 == count($this->lines) && empty($this->lines[1])) {
+                    try {
+                        $value = Inline::parse($this->lines[0]);
+                    } catch (ParseException $e) {
+                        $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+                        $e->setSnippet($this->currentLine);
+
+                        throw $e;
+                    }
+
+                    if (is_array($value)) {
+                        $first = reset($value);
+                        if (is_string($first) && '*' === substr($first, 0, 1)) {
+                            $data = array();
+                            foreach ($value as $alias) {
+                                $data[] = $this->refs[substr($alias, 1)];
+                            }
+                            $value = $data;
+                        }
+                    }
+
+                    if (isset($mbEncoding)) {
+                        mb_internal_encoding($mbEncoding);
+                    }
+
+                    return $value;
+                }
+
+                switch (preg_last_error()) {
+                    case PREG_INTERNAL_ERROR:
+                        $error = 'Internal PCRE error.';
+                        break;
+                    case PREG_BACKTRACK_LIMIT_ERROR:
+                        $error = 'pcre.backtrack_limit reached.';
+                        break;
+                    case PREG_RECURSION_LIMIT_ERROR:
+                        $error = 'pcre.recursion_limit reached.';
+                        break;
+                    case PREG_BAD_UTF8_ERROR:
+                        $error = 'Malformed UTF-8 data.';
+                        break;
+                    case PREG_BAD_UTF8_OFFSET_ERROR:
+                        $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
+                        break;
+                    default:
+                        $error = 'Unable to parse.';
+                }
+
+                throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+
+            if ($isRef) {
+                $this->refs[$isRef] = end($data);
+            }
+        }
+
+        if (isset($mbEncoding)) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return empty($data) ? null : $data;
+    }
+
+    /**
+     * Returns the current line number (takes the offset into account).
+     *
+     * @return integer The current line number
+     */
+    private function getRealCurrentLineNb()
+    {
+        return $this->currentLineNb + $this->offset;
+    }
+
+    /**
+     * Returns the current line indentation.
+     *
+     * @return integer The current line indentation
+     */
+    private function getCurrentLineIndentation()
+    {
+        return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
+    }
+
+    /**
+     * Returns the next embed block of YAML.
+     *
+     * @param integer $indentation The indent level at which the block is to be read, or null for default
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When indentation problem are detected
+     */
+    private function getNextEmbedBlock($indentation = null)
+    {
+        $this->moveToNextLine();
+
+        if (null === $indentation) {
+            $newIndent = $this->getCurrentLineIndentation();
+
+            if (!$this->isCurrentLineEmpty() && 0 == $newIndent) {
+                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+        } else {
+            $newIndent = $indentation;
+        }
+
+        $data = array(substr($this->currentLine, $newIndent));
+
+        while ($this->moveToNextLine()) {
+            if ($this->isCurrentLineEmpty()) {
+                if ($this->isCurrentLineBlank()) {
+                    $data[] = substr($this->currentLine, $newIndent);
+                }
+
+                continue;
+            }
+
+            $indent = $this->getCurrentLineIndentation();
+
+            if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match)) {
+                // empty line
+                $data[] = $match['text'];
+            } else if ($indent >= $newIndent) {
+                $data[] = substr($this->currentLine, $newIndent);
+            } else if (0 == $indent) {
+                $this->moveToPreviousLine();
+
+                break;
+            } else {
+                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+        }
+
+        return implode("\n", $data);
+    }
+
+    /**
+     * Moves the parser to the next line.
+     *
+     * @return Boolean
+     */
+    private function moveToNextLine()
+    {
+        if ($this->currentLineNb >= count($this->lines) - 1) {
+            return false;
+        }
+
+        $this->currentLine = $this->lines[++$this->currentLineNb];
+
+        return true;
+    }
+
+    /**
+     * Moves the parser to the previous line.
+     */
+    private function moveToPreviousLine()
+    {
+        $this->currentLine = $this->lines[--$this->currentLineNb];
+    }
+
+    /**
+     * Parses a YAML value.
+     *
+     * @param  string $value A YAML value
+     *
+     * @return mixed  A PHP value
+     *
+     * @throws ParseException When reference does not exist
+     */
+    private function parseValue($value)
+    {
+        if ('*' === substr($value, 0, 1)) {
+            if (false !== $pos = strpos($value, '#')) {
+                $value = substr($value, 1, $pos - 2);
+            } else {
+                $value = substr($value, 1);
+            }
+
+            if (!array_key_exists($value, $this->refs)) {
+                throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
+            }
+
+            return $this->refs[$value];
+        }
+
+        if (preg_match('/^(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?$/', $value, $matches)) {
+            $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
+
+            return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers)));
+        }
+
+        try {
+            return Inline::parse($value);
+        } catch (ParseException $e) {
+            $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+            $e->setSnippet($this->currentLine);
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Parses a folded scalar.
+     *
+     * @param  string  $separator   The separator that was used to begin this folded scalar (| or >)
+     * @param  string  $indicator   The indicator that was used to begin this folded scalar (+ or -)
+     * @param  integer $indentation The indentation that was used to begin this folded scalar
+     *
+     * @return string  The text value
+     */
+    private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
+    {
+        $separator = '|' == $separator ? "\n" : ' ';
+        $text = '';
+
+        $notEOF = $this->moveToNextLine();
+
+        while ($notEOF && $this->isCurrentLineBlank()) {
+            $text .= "\n";
+
+            $notEOF = $this->moveToNextLine();
+        }
+
+        if (!$notEOF) {
+            return '';
+        }
+
+        if (!preg_match('#^(?P<indent>'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P<text>.*)$#u', $this->currentLine, $matches)) {
+            $this->moveToPreviousLine();
+
+            return '';
+        }
+
+        $textIndent = $matches['indent'];
+        $previousIndent = 0;
+
+        $text .= $matches['text'].$separator;
+        while ($this->currentLineNb + 1 < count($this->lines)) {
+            $this->moveToNextLine();
+
+            if (preg_match('#^(?P<indent> {'.strlen($textIndent).',})(?P<text>.+)$#u', $this->currentLine, $matches)) {
+                if (' ' == $separator && $previousIndent != $matches['indent']) {
+                    $text = substr($text, 0, -1)."\n";
+                }
+                $previousIndent = $matches['indent'];
+
+                $text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator);
+            } else if (preg_match('#^(?P<text> *)$#', $this->currentLine, $matches)) {
+                $text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n";
+            } else {
+                $this->moveToPreviousLine();
+
+                break;
+            }
+        }
+
+        if (' ' == $separator) {
+            // replace last separator by a newline
+            $text = preg_replace('/ (\n*)$/', "\n$1", $text);
+        }
+
+        switch ($indicator) {
+            case '':
+                $text = preg_replace('#\n+$#s', "\n", $text);
+                break;
+            case '+':
+                break;
+            case '-':
+                $text = preg_replace('#\n+$#s', '', $text);
+                break;
+        }
+
+        return $text;
+    }
+
+    /**
+     * Returns true if the next line is indented.
+     *
+     * @return Boolean Returns true if the next line is indented, false otherwise
+     */
+    private function isNextLineIndented()
+    {
+        $currentIndentation = $this->getCurrentLineIndentation();
+        $notEOF = $this->moveToNextLine();
+
+        while ($notEOF && $this->isCurrentLineEmpty()) {
+            $notEOF = $this->moveToNextLine();
+        }
+
+        if (false === $notEOF) {
+            return false;
+        }
+
+        $ret = false;
+        if ($this->getCurrentLineIndentation() <= $currentIndentation) {
+            $ret = true;
+        }
+
+        $this->moveToPreviousLine();
+
+        return $ret;
+    }
+
+    /**
+     * Returns true if the current line is blank or if it is a comment line.
+     *
+     * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
+     */
+    private function isCurrentLineEmpty()
+    {
+        return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
+    }
+
+    /**
+     * Returns true if the current line is blank.
+     *
+     * @return Boolean Returns true if the current line is blank, false otherwise
+     */
+    private function isCurrentLineBlank()
+    {
+        return '' == trim($this->currentLine, ' ');
+    }
+
+    /**
+     * Returns true if the current line is a comment line.
+     *
+     * @return Boolean Returns true if the current line is a comment line, false otherwise
+     */
+    private function isCurrentLineComment()
+    {
+        //checking explicitly the first char of the trim is faster than loops or strpos
+        $ltrimmedLine = ltrim($this->currentLine, ' ');
+
+        return $ltrimmedLine[0] === '#';
+    }
+
+    /**
+     * Cleanups a YAML string to be parsed.
+     *
+     * @param  string $value The input YAML string
+     *
+     * @return string A cleaned up YAML string
+     */
+    private function cleanup($value)
+    {
+        $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+        if (!preg_match("#\n$#", $value)) {
+            $value .= "\n";
+        }
+
+        // strip YAML header
+        $count = 0;
+        $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count);
+        $this->offset += $count;
+
+        // remove leading comments
+        $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
+        if ($count == 1) {
+            // items have been removed, update the offset
+            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+            $value = $trimmedValue;
+        }
+
+        // remove start of the document marker (---)
+        $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
+        if ($count == 1) {
+            // items have been removed, update the offset
+            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+            $value = $trimmedValue;
+
+            // remove end of the document marker (...)
+            $value = preg_replace('#\.\.\.\s*$#s', '', $value);
+        }
+
+        return $value;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Unescaper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Unescaper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Unescaper.php	(revision 345)
@@ -0,0 +1,145 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Unescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Unescaper
+{
+    // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
+    // must be converted to that encoding.
+    const ENCODING = 'UTF-8';
+
+    // Regex fragment that matches an escaped character in a double quoted
+    // string.
+    const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
+
+    /**
+     * Unescapes a single quoted string.
+     *
+     * @param string $value A single quoted string.
+     *
+     * @return string The unescaped string.
+     */
+    public function unescapeSingleQuotedString($value)
+    {
+        return str_replace('\'\'', '\'', $value);
+    }
+
+    /**
+     * Unescapes a double quoted string.
+     *
+     * @param string $value A double quoted string.
+     *
+     * @return string The unescaped string.
+     */
+    public function unescapeDoubleQuotedString($value)
+    {
+        $self = $this;
+        $callback = function($match) use($self) {
+            return $self->unescapeCharacter($match[0]);
+        };
+
+        // evaluate the string
+        return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
+    }
+
+    /**
+     * Unescapes a character that was found in a double-quoted string
+     *
+     * @param string $value An escaped character
+     *
+     * @return string The unescaped character
+     */
+    public function unescapeCharacter($value)
+    {
+        switch ($value{1}) {
+            case '0':
+                return "\x0";
+            case 'a':
+                return "\x7";
+            case 'b':
+                return "\x8";
+            case 't':
+                return "\t";
+            case "\t":
+                return "\t";
+            case 'n':
+                return "\n";
+            case 'v':
+                return "\xb";
+            case 'f':
+                return "\xc";
+            case 'r':
+                return "\xd";
+            case 'e':
+                return "\x1b";
+            case ' ':
+                return ' ';
+            case '"':
+                return '"';
+            case '/':
+                return '/';
+            case '\\':
+                return '\\';
+            case 'N':
+                // U+0085 NEXT LINE
+                return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE');
+            case '_':
+                // U+00A0 NO-BREAK SPACE
+                return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE');
+            case 'L':
+                // U+2028 LINE SEPARATOR
+                return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE');
+            case 'P':
+                // U+2029 PARAGRAPH SEPARATOR
+                return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE');
+            case 'x':
+                $char = pack('n', hexdec(substr($value, 2, 2)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
+            case 'u':
+                $char = pack('n', hexdec(substr($value, 2, 4)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
+            case 'U':
+                $char = pack('N', hexdec(substr($value, 2, 8)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE');
+        }
+    }
+
+    /**
+     * Convert a string from one encoding to another.
+     *
+     * @param string $value The string to convert
+     * @param string $to    The input encoding
+     * @param string $from  The output encoding
+     *
+     * @return string The string with the new encoding
+     *
+     * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
+     */
+    private function convertEncoding($value, $to, $from)
+    {
+        if (function_exists('iconv')) {
+            return iconv($from, $to, $value);
+        } elseif (function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($value, $to, $from);
+        }
+
+        throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Yaml.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Yaml.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Doctrine/Symfony/Component/Yaml/Yaml.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Yaml offers convenience methods to load and dump YAML.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Yaml
+{
+    /**
+     * Parses YAML into a PHP array.
+     *
+     * The parse method, when supplied with a YAML stream (string or file),
+     * will do its best to convert YAML in a file into a PHP array.
+     *
+     *  Usage:
+     *  <code>
+     *   $array = Yaml::parse('config.yml');
+     *   print_r($array);
+     *  </code>
+     *
+     * @param string $input Path to a YAML file or a string containing YAML
+     *
+     * @return array The YAML converted to a PHP array
+     *
+     * @throws \InvalidArgumentException If the YAML is not valid
+     *
+     * @api
+     */
+    static public function parse($input)
+    {
+        $file = '';
+
+        // if input is a file, process it
+        if (strpos($input, "\n") === false && is_file($input) && is_readable($input)) {
+            $file = $input;
+
+            ob_start();
+            $retval = include($input);
+            $content = ob_get_clean();
+
+            // if an array is returned by the config file assume it's in plain php form else in YAML
+            $input = is_array($retval) ? $retval : $content;
+        }
+
+        // if an array is returned by the config file assume it's in plain php form else in YAML
+        if (is_array($input)) {
+            return $input;
+        }
+
+        $yaml = new Parser();
+
+        try {
+            return $yaml->parse($input);
+        } catch (ParseException $e) {
+            if ($file) {
+                $e->setParsedFile($file);
+            }
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Dumps a PHP array to a YAML string.
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.
+     *
+     * @param array   $array PHP array
+     * @param integer $inline The level where you switch to inline YAML
+     *
+     * @return string A YAML string representing the original PHP array
+     *
+     * @api
+     */
+    static public function dump($array, $inline = 2)
+    {
+        $yaml = new Dumper();
+
+        return $yaml->dump($array, $inline);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Pp/Pp.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Pp/Pp.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Pp/Pp.php	(revision 345)
@@ -0,0 +1,261 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+* @name Plenty Parser
+* @copyright 2011
+* @author Dwayne Charrington
+* @license http://philsturgeon.co.uk/code/dbad-license
+* @version 1.0
+*/
+
+class Pp extends CI_Driver_Library {
+    
+    /**
+    * Codeigniter instance
+    * 
+    * @var mixed
+    */
+    protected $ci;
+    
+    /**
+    * The driver to use for rendering
+    * 
+    * @var mixed
+    */
+    protected $_current_driver;
+    
+    /**
+    * Current theme in use
+    * 
+    * @var mixed
+    */
+    protected $_current_theme;
+    
+    /**
+    * Get default theme (if any)
+    * 
+    * @var mixed
+    */
+    protected $_default_theme;
+    
+    /**
+    * Theme locations
+    * 
+    * @var mixed
+    */
+    protected $_theme_locations = array();
+    
+    /**
+    * Are theming capabilities enabled or disabled?
+    * 
+    * @var mixed
+    */
+    protected $_theme_enabled;
+    
+    /**
+    * Valid drivers for rendering views
+    * 
+    * @var mixed
+    */
+    protected $valid_drivers = array(
+        'pp_smarty',
+        'pp_twig',
+    );
+    
+    /**
+    * Constructor
+    * 
+    */
+    public function __construct()
+    {
+        $this->ci = get_instance();
+        $this->ci->config->load('plentyparser');
+        
+        // Get our default driver
+        $this->_current_driver = config_item('parser.driver');
+        
+        // Get default theme (if one set)
+        $this->_default_theme = config_item('parser.theme.default');
+        
+        // Get whether or not themes are enabled or disabled
+        $this->_theme_enabled = config_item('parser.theme.enabled');
+        
+        // Call the init function
+        $this->_init();
+    }
+    
+    /**
+    * Init
+    * Populates variables and other things
+    * @returns void
+    */
+    private function _init()
+    {
+        // Is theming capability enabled
+        if ($this->_theme_enabled)
+        {
+            // Get all paths defined in the config file and add them to our array
+            foreach (config_item('parser.theme.locations') AS $path)
+            {
+                // If path isn't already in our array of paths
+                if ( !array_key_exists($path, $this->_theme_locations) )
+                {
+                    $this->_theme_locations[$path];
+                }
+            }
+            
+            // If no theme is set and we have a default, use that
+            if ( empty($this->_current_theme) AND !empty($this->_default_theme) )
+            {
+                $this->_current_theme = $this->_default_theme;
+            }
+            
+        }
+    }
+    
+    /**
+    * Call
+    * able to call native Smarty methods
+    * @returns void
+    */
+    public function __call($method, $params=array())
+    {
+		
+	if(!method_exists($this, $method))
+        {
+		call_user_func_array(array($this->{$this->_current_driver}, $method), $params);
+			
+	}
+    }
+    
+    /**
+    * Set Driver
+    * Sets which driver to use for view rendering
+    * 
+    * @param mixed $driver
+    * @returns void
+    */
+    public function set_driver($driver)
+    {
+        $driver = trim($driver);
+        
+        if ($driver == $this->_current_driver)
+        {
+            return true;
+        }
+        else
+        {
+            $this->_current_driver = $driver;   
+        }
+    }
+    
+    /**
+    * Set Theme
+    * Set the theme name we're using
+    * 
+    * @param mixed $theme
+    * @returns void
+    */
+    public function set_theme($theme)
+    {
+        $theme = trim($theme);
+        
+        if ($theme == $this->_current_theme)
+        {
+            return true;
+        }
+        else
+        {
+            $this->_current_theme = $theme;   
+        }
+    }
+    
+    /**
+    * Add Theme Location
+    * Add a new theme location
+    * 
+    * @param mixed $location
+    * @returns void
+    */
+    public function add_theme_location($location)
+    {
+        // If path isn't already in our array of paths
+        if ( !array_key_exists($location, $this->_theme_locations) )
+        {
+            $this->_theme_locations[$location];
+        }
+        
+        return true;
+    }
+    
+    /**
+    * Assign Var
+    * Set a variable name and value for a template
+    * 
+    * @param mixed $name
+    * @param mixed $value
+    * @returns void
+    */
+    public function assign_var($name, $value)
+    {
+        return $this->{$this->_current_driver}->assign_var($name, $value);
+    }
+    
+    /**
+    * Parse
+    * Parse will return the contents instead of displaying
+    * 
+    * @param mixed $template
+    * @param mixed $data
+    * @returns void
+    */
+    public function parse($template, $data = array(), $return = false, $driver = '')
+    {
+        
+        if (isset($GLOBALS['vskun']))
+        {
+            foreach ($GLOBALS['vskun'] as $index=>$val)
+            {
+                $data[$index]=$val;
+            }
+        }
+        
+        // Are we setting a particular driver to render with?
+        if ($driver !== '')
+        {
+            $this->_current_driver = trim($driver);
+        }
+        
+        // Add in the extension using the default if not supplied
+        if (!stripos($template, "."))
+        {
+            // If we have a parser template extension defined
+            if (config_item('parser.'.$this->_current_driver.'.extension'))
+            {
+                $template = $template.config_item('parser.'.$this->_current_driver.'.extension');   
+            }
+            else
+            {
+                show_error('No extension has been defined for the driver "'.$this->_current_driver.'". Please define one in the plentyparser.php config file.');
+            }
+        }
+        
+        // Call the driver parse function
+        return $this->{$this->_current_driver}->parse($template, $data, $return);
+    }
+    
+    /**
+    * Parse String
+    * Parse a string and return it as a string or display it
+    * 
+    * @param mixed $string
+    * @param mixed $data
+    * @param mixed $return
+    * @returns void
+    */
+    public function parse_string($string, $data = array(), $return = false)
+    {
+        return $this->{$this->_current_driver}->parse_string($string, $data, $return);
+    } 
+    
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_smarty.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_smarty.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_smarty.php	(revision 345)
@@ -0,0 +1,155 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+* @name Smarty
+* @package Plenty Parser
+* @subpackage Driver
+* @copyright 2011
+* @author Dwayne Charrington
+* @license http://philsturgeon.co.uk/code/dbad-license
+* @version 1.0
+*/
+
+class Pp_smarty extends CI_Driver {
+	
+	protected $ci;
+    
+    protected $_smarty;
+    
+    public function __construct()
+    {
+        $this->ci = get_instance();
+        $this->ci->config->load('plentyparser');
+
+        // Require Smarty
+        require_once APPPATH."third_party/Smarty/Smarty.class.php";
+        
+        // Store the Smarty library
+        $this->_smarty = new Smarty;
+        
+        // Smarty config options
+        $this->_smarty->setTemplateDir(config_item('parser.smarty.location'));
+        $this->_smarty->setCompileDir(config_item('parser.smarty.compile_dir'));
+        $this->_smarty->setCacheDir(config_item('parser.smarty.cache_dir'));
+        $this->_smarty->setConfigDir(config_item('parser.smarty.config_dir'));
+
+        // Add helper directories as plugin directories
+        $this->_smarty->addPluginsDir(FCPATH . 'system/helpers/');
+        $this->_smarty->addPluginsDir(APPPATH . 'helpers/');
+
+        // Delimiters
+        $this->_smarty->left_delimiter  = config_item("parser.smarty.left.delim");
+        $this->_smarty->right_delimiter = config_item("parser.smarty.right.delim");
+
+        // Cache life time in seconds
+        $this->_smarty->cache_lifetime  = config_item('parser.smarty.cache_lifetime');
+        
+        // Should let us access Codeigniter stuff in views
+        $this->assign_var("CI", $this->ci);
+
+        // Codeigniter base constants as variables.
+        $this->assign_var('APPPATH',APPPATH);
+        $this->assign_var('BASEPATH',BASEPATH);
+        $this->assign_var('FCPATH',FCPATH);
+
+        // Disable Smarty security policy
+        $this->_smarty->disableSecurity();
+        
+        // Turn on/off debug
+	$this->_smarty->debugging  = config_item('parser.smarty.debug');
+    }
+    
+    /**
+    * Call
+    * able to call native Smarty methods
+    * @returns void
+    */
+    public function __call($method, $params=array())
+    {
+		
+	if(!method_exists($this, $method))
+        {
+		call_user_func_array(array($this->_smarty, $method), $params);
+			
+	}
+    }
+    
+    /**
+    * Assign Var
+    * Assign a variable for template view use
+    * 
+    * @param mixed $name
+    * @param mixed $val
+    * @returns void
+    */
+    public function assign_var($name, $val)
+    {
+        // If an empty variable name
+        if (empty($name))
+        {
+            show_error('Smarty assign var function expects a name and value for assigning variables');
+        }
+        
+        // Call Smarty assign function
+        $this->_smarty->assign($name, $val);
+    }
+    
+    /**
+    * Parse
+    * Display or return template contents
+    * 
+    * @param mixed $template
+    * @param array $data
+    * @param mixed $return
+    */
+    public function parse($template, $data = array(), $return = false)
+    {        
+        // If we have variables to assign, lets assign them
+        if ($data)
+        {
+            foreach ($data AS $key => $val)
+            {
+                $this->_smarty->assign($key, $val);
+            }
+        }
+        
+        // If we're returning the template contents
+        if ($return === true)
+        {
+            return $this->_smarty->fetch($template);
+        }
+        else
+        {
+            $this->_smarty->display($template);
+        }
+    }
+    
+    /**
+    * Parse string
+    * Parses a string as a template and can be returned or displayed
+    * 
+    * @param mixed $string
+    * @param mixed $data
+    */
+    public function parse_string($string, $data = array())
+    {
+        return $this->_smarty->fetch('string:'.$string, $data);
+    }
+
+
+    /**
+     * Registers plugin to be used in templates
+     *
+     * @param string $type plugin type
+     * @param string $tag name of template tag
+     * @param callback $callback PHP callback to register
+     * @param boolean $cacheable if true (default) this fuction is cachable
+     * @param array $cache_attr caching attributes if any
+     * @throws SmartyException when the plugin tag is invalid
+     */
+    public function register_plugin($type, $tag, $callback, $cacheable = true, $cache_attr = null)
+    {
+        return $this->_smarty->registerPlugin($type, $tag, $callback, $cacheable, $cache_attr);
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_twig.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_twig.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/Pp/drivers/pp_twig.php	(revision 345)
@@ -0,0 +1,151 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+* @name Twig
+* @package Plenty Parser
+* @subpackage Driver
+* @copyright 2011
+* @author Dwayne Charrington
+* @license http://philsturgeon.co.uk/code/dbad-license
+* @version 1.0
+*/
+
+class Pp_twig extends CI_Driver {
+    
+    protected $ci;
+
+    protected $_twig;
+    
+    protected $_template;
+    
+    protected $_template_dir;
+    protected $_cache_dir;
+    protected $_debug;
+    
+    public function __construct()
+    {
+        $this->ci = get_instance();
+        
+        ini_set('include_path',
+        ini_get('include_path') . PATH_SEPARATOR . APPPATH . 'third_party/Twig');
+
+        require_once (string) "Autoloader" . EXT;
+
+        Twig_Autoloader::register();
+
+        $loader = new Twig_Loader_Filesystem($this->_template_dir);
+
+        $this->_twig = new Twig_Environment($loader, array(
+            'cache' => $this->_cache_dir,
+            'debug' => $this->_debug,
+        ));
+        
+        // Check if a theme has been set and if there is, check it exists and add it to the path
+             
+    }
+    
+    /**
+    * Override the default template location
+    * 
+    * @param mixed $location
+    * @returns void
+    */
+    public function set_location($location)
+    {
+        $this->_template_dir = $location;
+    }
+
+    /**
+     * Assign Var
+     * Assign a variable for template view use
+     *
+     * @param mixed $name
+     * @param mixed $val
+     * @returns void
+     */
+    public function assign_var($name, $val)
+    {
+        // If an empty variable name
+        if (empty($name))
+        {
+            show_error('Smarty assign var function expects a name and value for assigning variables');
+        }
+
+        // Call Smarty assign function
+        $this->_smarty->assign($name, $val);
+    }
+	
+    /**
+    * Load the template and return the data
+    * 
+    * @param mixed $template
+    * @param mixed $data
+    * @returns string
+    */
+	public function parse($template, $data = array(), $return = false)
+    {
+        // If we do not have a template extension, use the default
+        if (stripos($template, '.') === false)
+        {
+            $template . config_item('parser.twig.extension');
+        }
+
+        // Load the template
+        $template = $this->_twig->loadTemplate($template);
+
+        // If data supplied is an array
+        if ( is_array($data) )
+        {
+            $data = array_merge($data, $this->ci->load->get_vars());
+        }
+        
+        if ( $return === true )
+        {
+            return $template->render($data);   
+        }
+        else
+        {
+            return $template->display($data); 
+        }
+    }
+    
+    /**
+    * Parse String
+    * Parse a string and return it as a string or display it
+    * 
+    * @param mixed $string
+    * @param mixed $data
+    * @param mixed $return
+    * @returns void
+    */
+    public function parse_string($string, $data = array(), $return = false)
+    {
+        $string = $this->_twig->loadTemplate($string);
+        
+        if ( is_array($data) )
+        {
+            $data = array_merge($data, $this->ci->load->get_vars());
+        }
+        
+        if ($return === true)
+        {
+            return $string->render($data);
+        }
+        else
+        {
+            return $string->display($data);
+        }
+        
+    }
+
+    /**
+     * Register Plugin
+     * Registers a plugin for use in a Twig template.
+     * @param $name
+     */
+    public function register_plugin($name)
+    {
+        $this->_twig->addFunction($name, new Twig_Function_Function($name));
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/libraries/doctrine.php
===================================================================
--- pro-violet-viettel/sourcecode/application/libraries/doctrine.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/libraries/doctrine.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+// trailing slash is important!
+define('APPPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
+define('BASEPATH', APPPATH);
+define('ENVIRONMENT', 'production');
+
+require APPPATH.'libraries/Doctrine.php';
+
+$doctrine = new Doctrine();
+ 
+$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
+    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($doctrine->em->getConnection()),
+    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($doctrine->em)
+));
+
+$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen)', Doctrine\ORM\Version::VERSION);
+$cli->setCatchExceptions(true);
+$cli->setHelperSet($helperSet);
+$cli->addCommands(array(
+    // DBAL Commands
+    new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
+    new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
+ 
+    // ORM Commands
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
+    new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
+ 
+));
+$cli->run();
Index: pro-violet-viettel/sourcecode/application/models/Entities/Tblcollaborator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/models/Entities/Tblcollaborator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/models/Entities/Tblcollaborator.php	(revision 345)
@@ -0,0 +1,243 @@
+<?php
+
+namespace Entities;
+
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Entities\Tblcollaborator
+ */
+class Tblcollaborator
+{
+    /**
+     * @var integer $id
+     */
+    private $id;
+
+    /**
+     * @var string $full_name
+     */
+    private $full_name;
+
+    /**
+     * @var string $login_name
+     */
+    private $login_name;
+
+    /**
+     * @var string $cellphone
+     */
+    private $cellphone;
+
+    /**
+     * @var string $passwd
+     */
+    private $passwd;
+
+    /**
+     * @var integer $activated
+     */
+    private $activated;
+
+    /**
+     * @var string $created_time
+     */
+    private $created_time;
+
+    /**
+     * @var string $updated_time
+     */
+    private $updated_time;
+
+    /**
+     * @var integer $author
+     */
+    private $author;
+
+
+    /**
+     * Get id
+     *
+     * @return integer 
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Set full_name
+     *
+     * @param string $fullName
+     * @return Tblcollaborator
+     */
+    public function setFullName($fullName)
+    {
+        $this->full_name = $fullName;
+        return $this;
+    }
+
+    /**
+     * Get full_name
+     *
+     * @return string 
+     */
+    public function getFullName()
+    {
+        return $this->full_name;
+    }
+
+    /**
+     * Set login_name
+     *
+     * @param string $loginName
+     * @return Tblcollaborator
+     */
+    public function setLoginName($loginName)
+    {
+        $this->login_name = $loginName;
+        return $this;
+    }
+
+    /**
+     * Get login_name
+     *
+     * @return string 
+     */
+    public function getLoginName()
+    {
+        return $this->login_name;
+    }
+
+    /**
+     * Set cellphone
+     *
+     * @param string $cellphone
+     * @return Tblcollaborator
+     */
+    public function setCellphone($cellphone)
+    {
+        $this->cellphone = $cellphone;
+        return $this;
+    }
+
+    /**
+     * Get cellphone
+     *
+     * @return string 
+     */
+    public function getCellphone()
+    {
+        return $this->cellphone;
+    }
+
+    /**
+     * Set passwd
+     *
+     * @param string $passwd
+     * @return Tblcollaborator
+     */
+    public function setPasswd($passwd)
+    {
+        $this->passwd = $passwd;
+        return $this;
+    }
+
+    /**
+     * Get passwd
+     *
+     * @return string 
+     */
+    public function getPasswd()
+    {
+        return $this->passwd;
+    }
+
+    /**
+     * Set activated
+     *
+     * @param integer $activated
+     * @return Tblcollaborator
+     */
+    public function setActivated($activated)
+    {
+        $this->activated = $activated;
+        return $this;
+    }
+
+    /**
+     * Get activated
+     *
+     * @return integer 
+     */
+    public function getActivated()
+    {
+        return $this->activated;
+    }
+
+    /**
+     * Set created_time
+     *
+     * @param string $createdTime
+     * @return Tblcollaborator
+     */
+    public function setCreatedTime($createdTime)
+    {
+        $this->created_time = $createdTime;
+        return $this;
+    }
+
+    /**
+     * Get created_time
+     *
+     * @return string 
+     */
+    public function getCreatedTime()
+    {
+        return $this->created_time;
+    }
+
+    /**
+     * Set updated_time
+     *
+     * @param string $updatedTime
+     * @return Tblcollaborator
+     */
+    public function setUpdatedTime($updatedTime)
+    {
+        $this->updated_time = $updatedTime;
+        return $this;
+    }
+
+    /**
+     * Get updated_time
+     *
+     * @return string 
+     */
+    public function getUpdatedTime()
+    {
+        return $this->updated_time;
+    }
+
+    /**
+     * Set author
+     *
+     * @param integer $author
+     * @return Tblcollaborator
+     */
+    public function setAuthor($author)
+    {
+        $this->author = $author;
+        return $this;
+    }
+
+    /**
+     * Get author
+     *
+     * @return integer 
+     */
+    public function getAuthor()
+    {
+        return $this->author;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/models/Mappings/Entities.Tblcollaborator.dcm.yml
===================================================================
--- pro-violet-viettel/sourcecode/application/models/Mappings/Entities.Tblcollaborator.dcm.yml	(revision 345)
+++ pro-violet-viettel/sourcecode/application/models/Mappings/Entities.Tblcollaborator.dcm.yml	(revision 345)
@@ -0,0 +1,30 @@
+Entities\Tblcollaborator:
+    type: entity
+    id:
+        id:
+            type: integer
+            generator:
+                strategy: AUTO
+    table: tblcollaborator
+    fields:
+        full_name:
+            type: string
+            length: 45
+        login_name:
+            type: string
+            length: 45
+        cellphone:
+            type: string
+            length: 15
+        passwd:
+            type: string
+            length: 65
+        activated:
+            type: integer
+        created_time:
+            type: string
+        updated_time:
+            type: string
+        author:
+            type: integer
+        
Index: pro-violet-viettel/sourcecode/application/modules/admin/controllers/collaborator.php
===================================================================
--- pro-violet-viettel/sourcecode/application/modules/admin/controllers/collaborator.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/modules/admin/controllers/collaborator.php	(revision 345)
@@ -0,0 +1,107 @@
+<?php
+
+if (!defined('BASEPATH'))
+    exit('No direct script access allowed');
+
+class Collaborator extends MX_Controller {
+
+    public function __construct() {
+        parent::__construct();
+        $this->load->helper('cookie');
+    }
+
+    public function index() {
+        $data=array();
+        $this->load->driver("pp");
+        $admin_info = $this->session->userdata('adminInfo');
+        if ($admin_info) {
+            $data['content'] = $this->getCollaborators();
+            $this->parser->parse('collaborator/index',$data);
+        } else {
+            $this->load->view('login');
+        }
+    }
+    public function getCollaborators($filters=array())
+    {
+        $this->load->driver("pp");
+        $data['current_page'] = $this->uri->segment(4,1);
+        $data['itemsoptions']=array(10,25,50,100);
+        $data['perpage'] = 10;    
+        if ($this->input->post('items'))
+        {
+        $data['perpage'] = $this->input->post('items');    
+        }
+        
+        $data['keyword']='';
+        $sql=" FROM Entities\Tblcollaborator c";
+        if ($this->input->post('keyword'))
+        {
+        $sql.=" WHERE c.full_name LIKE '%".$this->input->post('keyword')."%'"; 
+        $data['keyword']=$this->input->post('keyword');
+        }
+        
+        $query = $this->doctrine->em->createQuery('SELECT COUNT(c.id) '.$sql);
+        $data['total'] = $query->getSingleScalarResult();
+        
+        $query = $this->doctrine->em->createQuery('SELECT c '.$sql);
+        $query->setFirstResult(($data['current_page']-1)*$data['perpage']);
+        $query->setMaxResults($data['perpage']);
+        $data['collaborators'] = $query->getArrayResult();
+        
+        
+        $this->load->library('pagination');
+        $url = "http://$_SERVER[HTTP_HOST]/admin/cong_tac_vien/trang/";
+        $config['base_url'] = $url;
+        $config['total_rows'] = $data['total'];
+        $config['use_page_numbers'] = TRUE;
+        $config['per_page'] = $data['perpage'];
+        $config['num_tag_open'] = "<li>";
+        $config['num_tag_close'] = "</li>";
+        $config['cur_tag_open'] = "<li class='active'><a>";
+        $config['cur_tag_close'] = '</a></li>';
+        $config['last_link'] = 'Â»';
+        $config['first_link'] = 'Â«';
+        $config['first_tag_open'] = "<li title='Trang Äáº§u tiÃªn'>";
+        $config['first_tag_close'] = '</li>';
+        $config['last_tag_open'] = "<li title='Trang cuá»i cÃ¹ng'>";
+        $config['last_tag_close'] = '</li>';
+        $config['next_link'] = '>';
+        $config['next_tag_open'] = "<li title='Trang káº¿ tiáº¿p'>";
+        $config['next_tag_close'] = '</li>';
+        $config['prev_link'] = '<';
+        $config['prev_tag_open'] = "<li title='Trang trÆ°á»c'>";
+        $config['prev_tag_close'] = '</li>';
+        $config['num_links'] = 2;
+        $config['current_page'] = $data['current_page'];
+        $config['ajax_class'] = 'ajax_paging';
+        $this->pagination->initialize($config);
+        $data['paging'] = $this->pagination->create_links();
+
+        if ($this->input->is_ajax_request()) {
+        return $this->pp->parse('modules/admin/views/collaborator/listview', $data);   
+        }
+        return $this->pp->parse('modules/admin/views/collaborator/listview', $data,true);   
+    }
+    public function test() {
+        for ($i = 1; $i <= 500; $i++) {
+            $collaborator = new Entities\Tblcollaborator();
+            $collaborator->setActivated(rand(0, 1));
+            $collaborator->setAuthor(1);
+            $collaborator->setCellphone('0' . (1695061706+$i));
+            $collaborator->setCreatedTime(date("Y-m-d H:i:s"));
+            $collaborator->setFullName("Full Name ".$i);
+            $collaborator->setLoginName("loginname".$i);
+            $collaborator->setPasswd(md5("12345678"));
+            $collaborator->setUpdatedTime(date("Y-m-d H:i:s"));
+            try {
+                $this->doctrine->em->persist($collaborator);
+                $this->doctrine->em->flush();
+                $result['success'] = 1;
+            } catch (Exception $e) {
+
+                echo $e;
+            }
+        }
+    }
+
+}
Index: pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/index.php
===================================================================
--- pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/index.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/index.php	(revision 345)
@@ -0,0 +1,75 @@
+<?php
+
+$base_url = base_url();
+$this->load->view('layout/admin/header', array('base_url' => $base_url));
+$this->load->view('layout/admin/sidebar', array('base_url' => $base_url));
+?>
+<script type="text/javascript">
+    function init_page()
+    {
+
+        $(".ajax_paging").click(function () {
+            $.ajax({
+                url: $(this).attr("href"),
+                type: "POST",
+                data: $("#collaborator").serialize(),
+                success: function (data, textStatus, jqXHR)
+                {
+                    // $result = jQuery.parseJSON(data);
+                    $("#content").html(data);
+                    init_page();
+
+                },
+                error: function (jqXHR, textStatus, errorThrown)
+                {
+                    $(".ajaxloading").hide();
+                }
+            });
+            return false;
+        })
+        $('#keyword').keyup(function (event) {
+            if (event.keyCode == '13') {              
+                filter();
+            }
+            return false;
+        });
+    }
+    
+    
+    function filter()
+    {
+        $.ajax({
+            url: 'http://viettel.violet.vn/admin/cong_tac_vien/trang/1',
+            type: "POST",
+            data: $("#collaborator").serialize(),
+            success: function (data, textStatus, jqXHR)
+            {
+                // $result = jQuery.parseJSON(data);
+                $("#content").html(data);
+                init_page();
+                $("#keyword").focus();
+                $("#keyword").setCursorToTextEnd();
+
+            },
+            error: function (jqXHR, textStatus, errorThrown)
+            {
+                $(".ajaxloading").hide();
+            }
+        });
+    }
+
+
+</script>
+<div class="main-content" id="content">
+    {content}
+</div><!-- /.main-content -->
+</div><!-- /.main-container-inner -->
+
+<a href="#" id="btn-scroll-up" class="btn-scroll-up btn btn-sm btn-inverse">
+    <i class="icon-double-angle-up icon-only bigger-110"></i>
+</a>
+</div><!-- /.main-container -->
+<?php
+
+$this->load->view('layout/admin/footer', array('base_url' => $base_url, 'adminjs' => array('assets/js/admin/collaborator.js')));
+?>
Index: pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/listview.php
===================================================================
--- pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/listview.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/modules/admin/views/collaborator/listview.php	(revision 345)
@@ -0,0 +1,265 @@
+<div id="breadcrumbs" class="breadcrumbs">
+    <script type="text/javascript">
+        try{literal}{{/literal}ace.settings.check('breadcrumbs' , 'fixed')}catch(e){}
+    </script>
+
+    <ul class="breadcrumb">
+        <li>
+            <i class="icon-home home-icon"></i>
+            <a href="#">Trang chá»§</a>
+        </li>
+
+        <li>
+            <a href="#">Quáº£n lÃœ tÃ i khoáº£n</a>
+        </li>
+        <li>
+            <a href="#">NgÆ°á»i dÃ¹ng</a>
+        </li>
+        <li class="active">Cá»ng tÃ¡c viÃªn</li>
+    </ul><!-- .breadcrumb -->
+
+    <div id="nav-search" class="nav-search">
+        <form class="form-search">
+            <span class="input-icon">
+                <input type="text" autocomplete="off" id="nav-search-input" class="nav-search-input" placeholder="TÃ¬m kiáº¿m ...">
+                <i class="icon-search nav-search-icon"></i>
+            </span>
+        </form>
+    </div><!-- #nav-search -->
+</div>
+<div class="page-content">
+    <div class="page-header">
+        <h1>
+            Cá»ng tÃ¡c viÃªn
+            <small>
+                <i class="icon-double-angle-right"></i>
+                thá»ng kÃª tÃ i khoáº£n
+            </small>
+        </h1>
+    </div><!-- /.page-header -->
+
+    <div class="row">
+        <div class="col-xs-12">
+            <!-- PAGE CONTENT BEGINS -->
+            <div style="padding-bottom:4px" class="table-header">
+                Thá»ng kÃª tÃ i khoáº£n
+
+                <button href="#addUser" data-toggle="modal" class="btn btn-success pull-right">
+                    <i class="icon-plus"></i>
+                    ThÃªm cá»ng tÃ¡c viÃªn
+                </button>
+
+            </div>
+
+            <div class="table-responsive">
+                <div role="grid" class="dataTables_wrapper" id="sample-table-2_wrapper">
+                    <form onsubmit="return false;" id="collaborator" >
+                    <div class="row">
+                        <div class="col-sm-6">
+                            <div id="sample-table-2_length" class="dataTables_length"><label>Hiá»n thá» 
+                                    <select onchange="filter();" name="items" size="1" aria-controls="sample-table-2">                                      
+                                        {foreach from=$itemsoptions item=option}
+                                        <option {if ({$option}=={$perpage})} selected{/if} value="{$option}">{$option}</option>
+                                        {/foreach}
+                                    </select> báº£n ghi</label>
+                            
+                            </div>
+                        </div>
+                        
+                        <div class="col-sm-6">
+                            <div class="dataTables_filter" id="sample-table-2_filter">
+                                <label>TÃ¬m kiáº¿m: 
+                                    <input type="text" name="keyword" id="keyword" value='{$keyword}' aria-controls="sample-table-2"></label>
+                            </div>
+                        </div>
+                    </div>
+                    </form>
+                    <table class="table table-striped table-bordered table-hover dataTable" id="sample-table-2" aria-describedby="sample-table-2_info">
+                        <thead>
+                            <tr role="row"><th class="center sorting_disabled" role="columnheader" rowspan="1" colspan="1" style="width: 44px;" aria-label="">
+                                    <label>
+                                        <input type="checkbox" class="ace">
+                                        <span class="lbl"></span>
+                                    </label>
+                                </th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 176px;" aria-label="Sá» Äiá»n thoáº¡i: activate to sort column ascending">Sá» Äiá»n thoáº¡i</th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 183px;" aria-label="Há» tÃªn: activate to sort column ascending">Há» tÃªn</th><th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 122px;" aria-label="Tiá»n: activate to sort column ascending">Tiá»n</th><th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 209px;" aria-label="
+
+                                                                                                                                                                                                        NgÃ y ÄÄng kÃœ
+                                                                                                                                                                                                        : activate to sort column ascending">
+                                    <i class="icon-time bigger-110 hidden-480"></i>
+                                    NgÃ y ÄÄng kÃœ
+                                </th><th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 158px;" aria-label="Tráº¡ng thÃ¡i: activate to sort column ascending">Tráº¡ng thÃ¡i</th><th class="sorting_disabled" role="columnheader" rowspan="1" colspan="1" style="width: 133px;" aria-label=""></th></tr>
+                        </thead>
+
+
+                        <tbody role="alert" aria-live="polite" aria-relevant="all">
+                            {foreach from=$collaborators item=collaborator}
+                            <tr class="odd">
+                                <td class="center  sorting_1">
+                                    <label>
+                                        <input type="checkbox" class="ace">
+                                        <span class="lbl"></span>
+                                    </label>
+                                </td>
+
+                                <td class=" ">
+                                    <a href="#">{$collaborator.cellphone}</a>
+                                </td>
+                                <td class=" ">{$collaborator.full_name}</td>
+                                <td class="hidden-480 ">3,330 VND</td>
+                                <td class=" ">{$collaborator.created_time}</td>
+
+                                <td class="hidden-480 ">
+                                    {if ({$collaborator.activated})==1}
+                                    <span class="label label-sm label-success">KÃ­ch hoáº¡t</span>
+                                    {/if}
+                                    {if ({$collaborator.activated})==0}
+                                    <span class="label label-sm label-default">ChÆ°a kÃ­ch hoáº¡t</span>
+                                    {/if}
+                                </td>
+
+                                <td class=" ">
+                                    <div class="visible-md visible-lg hidden-sm hidden-xs action-buttons">
+                                        <a href="#" class="blue">
+                                            <i class="icon-zoom-in bigger-130"></i>
+                                        </a>
+
+                                        <a href="#" class="green">
+                                            <i class="icon-pencil bigger-130"></i>
+                                        </a>
+
+                                        <a href="#" class="red">
+                                            <i class="icon-trash bigger-130"></i>
+                                        </a>
+                                    </div>
+
+                                    <div class="visible-xs visible-sm hidden-md hidden-lg">
+                                        <div class="inline position-relative">
+                                            <button data-toggle="dropdown" class="btn btn-minier btn-yellow dropdown-toggle">
+                                                <i class="icon-caret-down icon-only bigger-120"></i>
+                                            </button>
+
+                                            <ul class="dropdown-menu dropdown-only-icon dropdown-yellow pull-right dropdown-caret dropdown-close">
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-info" href="#" data-original-title="View">
+                                                        <span class="blue">
+                                                            <i class="icon-zoom-in bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-success" href="#" data-original-title="Edit">
+                                                        <span class="green">
+                                                            <i class="icon-edit bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+
+                                                <li>
+                                                    <a title="" data-rel="tooltip" class="tooltip-error" href="#" data-original-title="Delete">
+                                                        <span class="red">
+                                                            <i class="icon-trash bigger-120"></i>
+                                                        </span>
+                                                    </a>
+                                                </li>
+                                            </ul>
+                                        </div>
+                                    </div>
+                                </td>
+                            </tr>
+                            {/foreach}
+
+
+                            
+                        
+                        
+                        
+                        
+                        </tbody></table><div class="row"><div class="col-sm-6"><div class="dataTables_info" id="sample-table-2_info">Hiá»n thá» 1 Äáº¿n 2 cá»§a 2 báº£n ghi</div></div>
+                            <div class="col-sm-6">
+                                <div class="dataTables_paginate paging_bootstrap">
+                                    <ul class="pagination">
+                                        {$paging}
+                                    </ul>
+                                </div>
+                            </div>
+                        </div>
+                    
+                </div>
+            </div>
+
+            <div id="addUser" class="modal fade in" tabindex="-1">
+                <div class="modal-dialog">
+                    <div class="modal-content">
+                        <div class="modal-header no-padding">
+                            <div class="table-header">
+                                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
+                                    <span class="white">Ã</span>
+                                </button>
+                                ThÃªm cá»ng tÃ¡c viÃªn
+                            </div>
+                        </div>
+
+                        <div class="modal-body">
+                            <form class="form-horizontal" role="form">
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label no-padding-right" for="form-field-1"> TÃ i khoáº£n </label>
+
+                                    <div class="col-sm-9">
+                                        <span class="input-icon">
+                                            <input type="text" id="form-field-1" placeholder="TÃ i khoáº£n">
+                                            <i class="icon-user blue"></i>
+                                        </span>
+                                    </div>
+                                    <div class="help-block"> </div>
+                                </div>
+
+                                <div class="space-4"></div>
+
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label no-padding-right" for="form-field-2"> Máº­t kháº©u </label>
+
+                                    <div class="col-sm-9">
+                                        <span class="input-icon">
+                                            <input type="password" id="form-field-2" placeholder="Máº­t kháº©u">
+                                            <i class="icon-lock blue"></i>
+                                        </span>
+                                    </div>
+                                    <div class="help-block"> </div>
+                                </div>
+
+                                <div class="space-4"></div>
+
+                                <div class="clearfix form-actions">
+                                    <div class="col-md-offset-3 col-md-9">
+                                        <button class="btn btn-info" type="button">
+                                            <i class="icon-ok bigger-110"></i>
+                                            HoÃ n táº¥t
+                                        </button>
+
+                                        &nbsp; &nbsp; &nbsp;
+                                        <button class="btn" type="reset">
+                                            <i class="icon-undo bigger-110"></i>
+                                            XÃ³a háº¿t
+                                        </button>
+                                    </div>
+                                </div>
+
+                            </form></div>
+
+                    </div>
+                </div><!-- /.modal-content -->
+            </div><!-- /.modal-dialog -->
+        </div>
+
+        <!-- PAGE CONTENT ENDS -->
+    </div><!-- /.col -->
+</div>
+<script type="text/javascript">
+            window.onload = function ()
+{
+init_page();
+}
+
+
+</script>
Index: pro-violet-viettel/sourcecode/application/modules/admin/views/index.php
===================================================================
--- pro-violet-viettel/sourcecode/application/modules/admin/views/index.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/modules/admin/views/index.php	(revision 345)
@@ -183,4 +183,4 @@
 		</div><!-- /.main-container -->
 <?php 
-$this->load->view('layout/admin/footer', array('base_url' => $base_url));
+$this->load->view('layout/admin/footer', array('base_url' => $base_url, 'adminjs' => array('admin/collaborator.js',)));
 ?>
Index: pro-violet-viettel/sourcecode/application/modules/admin/views/test.php
===================================================================
--- pro-violet-viettel/sourcecode/application/modules/admin/views/test.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/modules/admin/views/test.php	(revision 345)
@@ -0,0 +1,1 @@
+456
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/Smarty.class.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/Smarty.class.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/Smarty.class.php	(revision 345)
@@ -0,0 +1,1502 @@
+<?php
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty.class.php
+ * SVN:         $Id: Smarty.class.php 4518 2011-12-18 18:48:07Z rodneyrehm $
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ * @package Smarty
+ * @version 3.1.7
+ */
+
+/**
+ * define shorthand directory separator constant
+ */
+if (!defined('DS')) {
+    define('DS', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * Sets SMARTY_DIR only if user application has not already defined it.
+ */
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', dirname(__FILE__) . DS);
+}
+
+/**
+ * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
+ * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
+ */
+if (!defined('SMARTY_SYSPLUGINS_DIR')) {
+    define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
+}
+if (!defined('SMARTY_PLUGINS_DIR')) {
+    define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
+}
+if (!defined('SMARTY_MBSTRING')) {
+    define('SMARTY_MBSTRING', function_exists('mb_strlen'));
+}
+if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
+    // UTF-8 can only be done properly when mbstring is available!
+    /**
+     * @deprecated in favor of Smarty::$_CHARSET
+     */
+    define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
+}
+if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
+    /**
+     * @deprecated in favor of Smarty::$_DATE_FORMAT
+     */
+    define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
+}
+
+/**
+ * register the class autoloader
+ */
+if (!defined('SMARTY_SPL_AUTOLOAD')) {
+    define('SMARTY_SPL_AUTOLOAD', 0);
+}
+
+if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
+    $registeredAutoLoadFunctions = spl_autoload_functions();
+    if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
+        spl_autoload_register();
+    }
+} else {
+    spl_autoload_register('smartyAutoload');
+}
+
+/**
+ * Load always needed external class files
+ */
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php';
+include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php';
+
+/**
+ * This is the main Smarty class
+ * @package Smarty
+ */
+class Smarty extends Smarty_Internal_TemplateBase {
+
+    /**#@+
+     * constant definitions
+     */
+
+    /**
+     * smarty version
+     */
+    const SMARTY_VERSION = 'Smarty-3.1.7';
+
+    /**
+     * define variable scopes
+     */
+    const SCOPE_LOCAL = 0;
+    const SCOPE_PARENT = 1;
+    const SCOPE_ROOT = 2;
+    const SCOPE_GLOBAL = 3;
+    /**
+     * define caching modes
+     */
+    const CACHING_OFF = 0;
+    const CACHING_LIFETIME_CURRENT = 1;
+    const CACHING_LIFETIME_SAVED = 2;
+    /**
+     * define compile check modes
+     */
+    const COMPILECHECK_OFF = 0;
+    const COMPILECHECK_ON = 1;
+    const COMPILECHECK_CACHEMISS = 2;
+    /**
+     * modes for handling of "<?php ... ?>" tags in templates.
+     */
+    const PHP_PASSTHRU = 0; //-> print tags as plain text
+    const PHP_QUOTE = 1; //-> escape tags as entities
+    const PHP_REMOVE = 2; //-> escape tags as entities
+    const PHP_ALLOW = 3; //-> escape tags as entities
+    /**
+     * filter types
+     */
+    const FILTER_POST = 'post';
+    const FILTER_PRE = 'pre';
+    const FILTER_OUTPUT = 'output';
+    const FILTER_VARIABLE = 'variable';
+    /**
+     * plugin types
+     */
+    const PLUGIN_FUNCTION = 'function';
+    const PLUGIN_BLOCK = 'block';
+    const PLUGIN_COMPILER = 'compiler';
+    const PLUGIN_MODIFIER = 'modifier';
+    const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
+
+    /**#@-*/
+
+    /**
+     * assigned global tpl vars
+     */
+    public static $global_tpl_vars = array();
+
+    /**
+     * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
+     */
+    public static $_previous_error_handler = null;
+    /**
+     * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
+     */
+    public static $_muted_directories = array();
+    /**
+     * Flag denoting if Multibyte String functions are available
+     */
+    public static $_MBSTRING = SMARTY_MBSTRING;
+    /**
+     * The character set to adhere to (e.g. "UTF-8")
+     */
+    public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
+    /**
+     * The date format to be used internally
+     * (accepts date() and strftime())
+     */
+    public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
+    /**
+     * Flag denoting if PCRE should run in UTF-8 mode
+     */
+    public static $_UTF8_MODIFIER = 'u';
+    
+    
+    /**#@+
+     * variables
+     */
+
+    /**
+     * auto literal on delimiters with whitspace
+     * @var boolean
+     */
+    public $auto_literal = true;
+    /**
+     * display error on not assigned variables
+     * @var boolean
+     */
+    public $error_unassigned = false;
+    /**
+     * look up relative filepaths in include_path
+     * @var boolean
+     */
+    public $use_include_path = false;
+    /**
+     * template directory
+     * @var array
+     */
+    private $template_dir = array();
+    /**
+     * joined template directory string used in cache keys
+     * @var string
+     */
+    public $joined_template_dir = null;
+    /**
+     * joined config directory string used in cache keys
+     * @var string
+     */
+    public $joined_config_dir = null;
+    /**
+     * default template handler
+     * @var callable
+     */
+    public $default_template_handler_func = null;
+    /**
+     * default config handler
+     * @var callable
+     */
+    public $default_config_handler_func = null;
+    /**
+     * default plugin handler
+     * @var callable
+     */
+    public $default_plugin_handler_func = null;
+    /**
+     * compile directory
+     * @var string
+     */
+    private $compile_dir = null;
+    /**
+     * plugins directory
+     * @var array
+     */
+    private $plugins_dir = array();
+    /**
+     * cache directory
+     * @var string
+     */
+    private $cache_dir = null;
+    /**
+     * config directory
+     * @var array
+     */
+    private $config_dir = array();
+    /**
+     * force template compiling?
+     * @var boolean
+     */
+    public $force_compile = false;
+    /**
+     * check template for modifications?
+     * @var boolean
+     */
+    public $compile_check = true;
+    /**
+     * use sub dirs for compiled/cached files?
+     * @var boolean
+     */
+    public $use_sub_dirs = false;
+    /**
+     * allow ambiguous resources (that are made unique by the resource handler)
+     * @var boolean
+     */
+    public $allow_ambiguous_resources = false;
+    /**
+     * caching enabled
+     * @var boolean
+     */
+    public $caching = false;
+    /**
+     * merge compiled includes
+     * @var boolean
+     */
+    public $merge_compiled_includes = false;
+    /**
+     * cache lifetime in seconds
+     * @var integer
+     */
+    public $cache_lifetime = 3600;
+    /**
+     * force cache file creation
+     * @var boolean
+     */
+    public $force_cache = false;
+    /**
+     * Set this if you want different sets of cache files for the same
+     * templates.
+     *
+     * @var string
+     */
+    public $cache_id = null;
+    /**
+     * Set this if you want different sets of compiled files for the same
+     * templates.
+     *
+     * @var string
+     */
+    public $compile_id = null;
+    /**
+     * template left-delimiter
+     * @var string
+     */
+    public $left_delimiter = "{";
+    /**
+     * template right-delimiter
+     * @var string
+     */
+    public $right_delimiter = "}";
+    /**#@+
+     * security
+     */
+    /**
+     * class name
+     *
+     * This should be instance of Smarty_Security.
+     *
+     * @var string
+     * @see Smarty_Security
+     */
+    public $security_class = 'Smarty_Security';
+    /**
+     * implementation of security class
+     *
+     * @var Smarty_Security
+     */
+    public $security_policy = null;
+    /**
+     * controls handling of PHP-blocks
+     *
+     * @var integer
+     */
+    public $php_handling = self::PHP_PASSTHRU;
+    /**
+     * controls if the php template file resource is allowed
+     *
+     * @var bool
+     */
+    public $allow_php_templates = false;
+    /**
+     * Should compiled-templates be prevented from being called directly?
+     *
+     * {@internal
+     * Currently used by Smarty_Internal_Template only.
+     * }}
+     *
+     * @var boolean
+     */
+    public $direct_access_security = true;
+    /**#@-*/
+    /**
+     * debug mode
+     *
+     * Setting this to true enables the debug-console.
+     *
+     * @var boolean
+     */
+    public $debugging = false;
+    /**
+     * This determines if debugging is enable-able from the browser.
+     * <ul>
+     *  <li>NONE => no debugging control allowed</li>
+     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+     * </ul>
+     * @var string
+     */
+    public $debugging_ctrl = 'NONE';
+    /**
+     * Name of debugging URL-param.
+     *
+     * Only used when $debugging_ctrl is set to 'URL'.
+     * The name of the URL-parameter that activates debugging.
+     *
+     * @var type
+     */
+    public $smarty_debug_id = 'SMARTY_DEBUG';
+    /**
+     * Path of debug template.
+     * @var string
+     */
+    public $debug_tpl = null;
+    /**
+     * When set, smarty uses this value as error_reporting-level.
+     * @var int
+     */
+    public $error_reporting = null;
+    /**
+     * Internal flag for getTags()
+     * @var boolean
+     */
+    public $get_used_tags = false;
+
+    /**#@+
+     * config var settings
+     */
+
+    /**
+     * Controls whether variables with the same name overwrite each other.
+     * @var boolean
+     */
+    public $config_overwrite = true;
+    /**
+     * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
+     * @var boolean
+     */
+    public $config_booleanize = true;
+    /**
+     * Controls whether hidden config sections/vars are read from the file.
+     * @var boolean
+     */
+    public $config_read_hidden = false;
+
+    /**#@-*/
+
+    /**#@+
+     * resource locking
+     */
+
+    /**
+     * locking concurrent compiles
+     * @var boolean
+     */
+    public $compile_locking = true;
+    /**
+     * Controls whether cache resources should emply locking mechanism
+     * @var boolean
+     */
+    public $cache_locking = false;
+    /**
+     * seconds to wait for acquiring a lock before ignoring the write lock
+     * @var float
+     */
+    public $locking_timeout = 10;
+
+    /**#@-*/
+
+    /**
+     * global template functions
+     * @var array
+     */
+    public $template_functions = array();
+    /**
+     * resource type used if none given
+     *
+     * Must be an valid key of $registered_resources.
+     * @var string
+     */
+    public $default_resource_type = 'file';
+    /**
+     * caching type
+     *
+     * Must be an element of $cache_resource_types.
+     *
+     * @var string
+     */
+    public $caching_type = 'file';
+    /**
+     * internal config properties
+     * @var array
+     */
+    public $properties = array();
+    /**
+     * config type
+     * @var string
+     */
+    public $default_config_type = 'file';
+    /**
+     * cached template objects
+     * @var array
+     */
+    public $template_objects = array();
+    /**
+     * check If-Modified-Since headers
+     * @var boolean
+     */
+    public $cache_modified_check = false;
+    /**
+     * registered plugins
+     * @var array
+     */
+    public $registered_plugins = array();
+    /**
+     * plugin search order
+     * @var array
+     */
+    public $plugin_search_order = array('function', 'block', 'compiler', 'class');
+    /**
+     * registered objects
+     * @var array
+     */
+    public $registered_objects = array();
+    /**
+     * registered classes
+     * @var array
+     */
+    public $registered_classes = array();
+    /**
+     * registered filters
+     * @var array
+     */
+    public $registered_filters = array();
+    /**
+     * registered resources
+     * @var array
+     */
+    public $registered_resources = array();
+    /**
+     * resource handler cache
+     * @var array
+     */
+    public $_resource_handlers = array();
+    /**
+     * registered cache resources
+     * @var array
+     */
+    public $registered_cache_resources = array();
+    /**
+     * cache resource handler cache
+     * @var array
+     */
+    public $_cacheresource_handlers = array();
+    /**
+     * autoload filter
+     * @var array
+     */
+    public $autoload_filters = array();
+    /**
+     * default modifier
+     * @var array
+     */
+    public $default_modifiers = array();
+    /**
+     * autoescape variable output
+     * @var boolean
+     */
+    public $escape_html = false;
+    /**
+     * global internal smarty vars
+     * @var array
+     */
+    public static $_smarty_vars = array();
+    /**
+     * start time for execution time calculation
+     * @var int
+     */
+    public $start_time = 0;
+    /**
+     * default file permissions
+     * @var int
+     */
+    public $_file_perms = 0644;
+    /**
+     * default dir permissions
+     * @var int
+     */
+    public $_dir_perms = 0771;
+    /**
+     * block tag hierarchy
+     * @var array
+     */
+    public $_tag_stack = array();
+    /**
+     * self pointer to Smarty object
+     * @var Smarty
+     */
+    public $smarty;
+    /**
+     * required by the compiler for BC
+     * @var string
+     */
+    public $_current_file = null;
+    /**
+     * internal flag to enable parser debugging
+     * @var bool
+     */
+    public $_parserdebug = false;
+    /**
+     * Saved parameter of merged templates during compilation
+     *
+     * @var array
+     */
+    public $merged_templates_func = array();
+    /**#@-*/
+
+    /**
+     * Initialize new Smarty object
+     *
+     */
+    public function __construct()
+    {
+        // selfpointer needed by some other class methods
+        $this->smarty = $this;
+        if (is_callable('mb_internal_encoding')) {
+            mb_internal_encoding(Smarty::$_CHARSET);
+        }
+        $this->start_time = microtime(true);
+        // set default dirs
+        $this->setTemplateDir('.' . DS . 'templates' . DS)
+            ->setCompileDir('.' . DS . 'templates_c' . DS)
+            ->setPluginsDir(SMARTY_PLUGINS_DIR)
+            ->setCacheDir('.' . DS . 'cache' . DS)
+            ->setConfigDir('.' . DS . 'configs' . DS);
+
+        $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
+        if (isset($_SERVER['SCRIPT_NAME'])) {
+            $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
+        }
+    }
+
+
+    /**
+     * Class destructor
+     */
+    public function __destruct()
+    {
+        // intentionally left blank
+    }
+
+    /**
+     * <<magic>> set selfpointer on cloned object
+     */
+    public function __clone()
+    {
+        $this->smarty = $this;
+    }
+
+
+    /**
+     * <<magic>> Generic getter.
+     *
+     * Calls the appropriate getter function.
+     * Issues an E_USER_NOTICE if no valid getter is found.
+     *
+     * @param string $name property name
+     * @return mixed
+     */
+    public function __get($name)
+    {
+        $allowed = array(
+        'template_dir' => 'getTemplateDir',
+        'config_dir' => 'getConfigDir',
+        'plugins_dir' => 'getPluginsDir',
+        'compile_dir' => 'getCompileDir',
+        'cache_dir' => 'getCacheDir',
+        );
+
+        if (isset($allowed[$name])) {
+            return $this->{$allowed[$name]}();
+        } else {
+            trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE);
+        }
+    }
+
+    /**
+     * <<magic>> Generic setter.
+     *
+     * Calls the appropriate setter function.
+     * Issues an E_USER_NOTICE if no valid setter is found.
+     *
+     * @param string $name  property name
+     * @param mixed  $value parameter passed to setter
+     */
+    public function __set($name, $value)
+    {
+        $allowed = array(
+        'template_dir' => 'setTemplateDir',
+        'config_dir' => 'setConfigDir',
+        'plugins_dir' => 'setPluginsDir',
+        'compile_dir' => 'setCompileDir',
+        'cache_dir' => 'setCacheDir',
+        );
+
+        if (isset($allowed[$name])) {
+            $this->{$allowed[$name]}($value);
+        } else {
+            trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
+        }
+    }
+
+    /**
+     * Check if a template resource exists
+     *
+     * @param string $resource_name template name
+     * @return boolean status
+     */
+    public function templateExists($resource_name)
+    {
+        // create template object
+        $save = $this->template_objects;
+        $tpl = new $this->template_class($resource_name, $this);
+        // check if it does exists
+        $result = $tpl->source->exists;
+        $this->template_objects = $save;
+        return $result;
+    }
+
+    /**
+     * Returns a single or all global  variables
+     *
+     * @param object $smarty
+     * @param string $varname variable name or null
+     * @return string variable value or or array of variables
+     */
+    public function getGlobal($varname = null)
+    {
+        if (isset($varname)) {
+            if (isset(self::$global_tpl_vars[$varname])) {
+                return self::$global_tpl_vars[$varname]->value;
+            } else {
+                return '';
+            }
+        } else {
+            $_result = array();
+            foreach (self::$global_tpl_vars AS $key => $var) {
+                $_result[$key] = $var->value;
+            }
+            return $_result;
+        }
+    }
+
+    /**
+     * Empty cache folder
+     *
+     * @param integer $exp_time expiration time
+     * @param string  $type     resource type
+     * @return integer number of cache files deleted
+     */
+    function clearAllCache($exp_time = null, $type = null)
+    {
+        // load cache resource and call clearAll
+        $_cache_resource = Smarty_CacheResource::load($this, $type);
+        Smarty_CacheResource::invalidLoadedCache($this);
+        return $_cache_resource->clearAll($this, $exp_time);
+    }
+
+    /**
+     * Empty cache for a specific template
+     *
+     * @param string  $template_name template name
+     * @param string  $cache_id      cache id
+     * @param string  $compile_id    compile id
+     * @param integer $exp_time      expiration time
+     * @param string  $type          resource type
+     * @return integer number of cache files deleted
+     */
+    public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
+    {
+        // load cache resource and call clear
+        $_cache_resource = Smarty_CacheResource::load($this, $type);
+        Smarty_CacheResource::invalidLoadedCache($this);
+        return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
+    }
+
+    /**
+     * Loads security class and enables security
+     *
+     * @param string|Smarty_Security $security_class if a string is used, it must be class-name
+     * @return Smarty current Smarty instance for chaining
+     * @throws SmartyException when an invalid class name is provided
+     */
+    public function enableSecurity($security_class = null)
+    {
+        if ($security_class instanceof Smarty_Security) {
+            $this->security_policy = $security_class;
+            return $this;
+        } elseif (is_object($security_class)) {
+            throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
+        }
+        if ($security_class == null) {
+            $security_class = $this->security_class;
+        }
+        if (!class_exists($security_class)) {
+            throw new SmartyException("Security class '$security_class' is not defined");
+        } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
+            throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
+        } else {
+            $this->security_policy = new $security_class($this);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disable security
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function disableSecurity()
+    {
+        $this->security_policy = null;
+
+        return $this;
+    }
+
+    /**
+     * Set template directory
+     *
+     * @param string|array $template_dir directory(s) of template sources
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setTemplateDir($template_dir)
+    {
+        $this->template_dir = array();
+        foreach ((array) $template_dir as $k => $v) {
+            $this->template_dir[$k] = rtrim($v, '/\\') . DS;
+        }
+
+        $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
+        return $this;
+    }
+
+    /**
+     * Add template directory(s)
+     *
+     * @param string|array $template_dir directory(s) of template sources
+     * @param string       $key          of the array element to assign the template dir to
+     * @return Smarty current Smarty instance for chaining
+     * @throws SmartyException when the given template directory is not valid
+     */
+    public function addTemplateDir($template_dir, $key=null)
+    {
+        // make sure we're dealing with an array
+        $this->template_dir = (array) $this->template_dir;
+
+        if (is_array($template_dir)) {
+            foreach ($template_dir as $k => $v) {
+                if (is_int($k)) {
+                    // indexes are not merged but appended
+                    $this->template_dir[] = rtrim($v, '/\\') . DS;
+                } else {
+                    // string indexes are overridden
+                    $this->template_dir[$k] = rtrim($v, '/\\') . DS;
+                }
+            }
+        } elseif ($key !== null) {
+            // override directory at specified index
+            $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS;
+        } else {
+            // append new directory
+            $this->template_dir[] = rtrim($template_dir, '/\\') . DS;
+        }
+        $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
+        return $this;
+    }
+
+    /**
+     * Get template directories
+     *
+     * @param mixed index of directory to get, null to get all
+     * @return array|string list of template directories, or directory of $index
+     */
+    public function getTemplateDir($index=null)
+    {
+        if ($index !== null) {
+            return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
+        }
+
+        return (array)$this->template_dir;
+    }
+
+    /**
+     * Set config directory
+     *
+     * @param string|array $template_dir directory(s) of configuration sources
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setConfigDir($config_dir)
+    {
+        $this->config_dir = array();
+        foreach ((array) $config_dir as $k => $v) {
+            $this->config_dir[$k] = rtrim($v, '/\\') . DS;
+        }
+
+        $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
+        return $this;
+    }
+
+    /**
+     * Add config directory(s)
+     *
+     * @param string|array $config_dir directory(s) of config sources
+     * @param string key of the array element to assign the config dir to
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function addConfigDir($config_dir, $key=null)
+    {
+        // make sure we're dealing with an array
+        $this->config_dir = (array) $this->config_dir;
+
+        if (is_array($config_dir)) {
+            foreach ($config_dir as $k => $v) {
+                if (is_int($k)) {
+                    // indexes are not merged but appended
+                    $this->config_dir[] = rtrim($v, '/\\') . DS;
+                } else {
+                    // string indexes are overridden
+                    $this->config_dir[$k] = rtrim($v, '/\\') . DS;
+                }
+            }
+        } elseif( $key !== null ) {
+            // override directory at specified index
+            $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS;
+        } else {
+            // append new directory
+            $this->config_dir[] = rtrim($config_dir, '/\\') . DS;
+        }
+
+        $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
+        return $this;
+    }
+
+    /**
+     * Get config directory
+     *
+     * @param mixed index of directory to get, null to get all
+     * @return array|string configuration directory
+     */
+    public function getConfigDir($index=null)
+    {
+        if ($index !== null) {
+            return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
+        }
+
+        return (array)$this->config_dir;
+    }
+
+    /**
+     * Set plugins directory
+     *
+     * @param string|array $plugins_dir directory(s) of plugins
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setPluginsDir($plugins_dir)
+    {
+        $this->plugins_dir = array();
+        foreach ((array)$plugins_dir as $k => $v) {
+            $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds directory of plugin files
+     *
+     * @param object $smarty
+     * @param string $ |array $ plugins folder
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function addPluginsDir($plugins_dir)
+    {
+        // make sure we're dealing with an array
+        $this->plugins_dir = (array) $this->plugins_dir;
+
+        if (is_array($plugins_dir)) {
+            foreach ($plugins_dir as $k => $v) {
+                if (is_int($k)) {
+                    // indexes are not merged but appended
+                    $this->plugins_dir[] = rtrim($v, '/\\') . DS;
+                } else {
+                    // string indexes are overridden
+                    $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
+                }
+            }
+        } else {
+            // append new directory
+            $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS;
+        }
+
+        $this->plugins_dir = array_unique($this->plugins_dir);
+        return $this;
+    }
+
+    /**
+     * Get plugin directories
+     *
+     * @return array list of plugin directories
+     */
+    public function getPluginsDir()
+    {
+        return (array)$this->plugins_dir;
+    }
+
+    /**
+     * Set compile directory
+     *
+     * @param string $compile_dir directory to store compiled templates in
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setCompileDir($compile_dir)
+    {
+        $this->compile_dir = rtrim($compile_dir, '/\\') . DS;
+        if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
+            Smarty::$_muted_directories[$this->compile_dir] = null;
+        }
+        return $this;
+    }
+
+    /**
+     * Get compiled directory
+     *
+     * @return string path to compiled templates
+     */
+    public function getCompileDir()
+    {
+        return $this->compile_dir;
+    }
+
+    /**
+     * Set cache directory
+     *
+     * @param string $cache_dir directory to store cached templates in
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setCacheDir($cache_dir)
+    {
+        $this->cache_dir = rtrim($cache_dir, '/\\') . DS;
+        if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
+            Smarty::$_muted_directories[$this->cache_dir] = null;
+        }
+        return $this;
+    }
+
+    /**
+     * Get cache directory
+     *
+     * @return string path of cache directory
+     */
+    public function getCacheDir()
+    {
+        return $this->cache_dir;
+    }
+
+    /**
+     * Set default modifiers
+     *
+     * @param array|string $modifiers modifier or list of modifiers to set
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setDefaultModifiers($modifiers)
+    {
+        $this->default_modifiers = (array) $modifiers;
+        return $this;
+    }
+
+    /**
+     * Add default modifiers
+     *
+     * @param array|string $modifiers modifier or list of modifiers to add
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function addDefaultModifiers($modifiers)
+    {
+        if (is_array($modifiers)) {
+            $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
+        } else {
+            $this->default_modifiers[] = $modifiers;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get default modifiers
+     *
+     * @return array list of default modifiers
+     */
+    public function getDefaultModifiers()
+    {
+        return $this->default_modifiers;
+    }
+
+
+    /**
+     * Set autoload filters
+     *
+     * @param array $filters filters to load automatically
+     * @param string $type "pre", "output", âŠ specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function setAutoloadFilters($filters, $type=null)
+    {
+        if ($type !== null) {
+            $this->autoload_filters[$type] = (array) $filters;
+        } else {
+            $this->autoload_filters = (array) $filters;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add autoload filters
+     *
+     * @param array $filters filters to load automatically
+     * @param string $type "pre", "output", âŠ specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
+     * @return Smarty current Smarty instance for chaining
+     */
+    public function addAutoloadFilters($filters, $type=null)
+    {
+        if ($type !== null) {
+            if (!empty($this->autoload_filters[$type])) {
+                $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
+            } else {
+                $this->autoload_filters[$type] = (array) $filters;
+            }
+        } else {
+            foreach ((array) $filters as $key => $value) {
+                if (!empty($this->autoload_filters[$key])) {
+                    $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
+                } else {
+                    $this->autoload_filters[$key] = (array) $value;
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get autoload filters
+     *
+     * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
+     * @return array array( 'type1' => array( 'filter1', 'filter2', âŠ ) ) or array( 'filter1', 'filter2', âŠ) if $type was specified
+     */
+    public function getAutoloadFilters($type=null)
+    {
+        if ($type !== null) {
+            return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
+        }
+
+        return $this->autoload_filters;
+    }
+
+    /**
+     * return name of debugging template
+     *
+     * @return string
+     */
+    public function getDebugTemplate()
+    {
+        return $this->debug_tpl;
+    }
+
+    /**
+     * set the debug template
+     *
+     * @param string $tpl_name
+     * @return Smarty current Smarty instance for chaining
+     * @throws SmartyException if file is not readable
+     */
+    public function setDebugTemplate($tpl_name)
+    {
+        if (!is_readable($tpl_name)) {
+            throw new SmartyException("Unknown file '{$tpl_name}'");
+        }
+        $this->debug_tpl = $tpl_name;
+
+        return $this;
+    }
+
+    /**
+     * creates a template object
+     *
+     * @param string $template the resource handle of the template file
+     * @param mixed $cache_id cache id to be used with this template
+     * @param mixed $compile_id compile id to be used with this template
+     * @param object $parent next higher level of Smarty variables
+     * @param boolean $do_clone flag is Smarty object shall be cloned
+     * @return object template object
+     */
+    public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
+    {
+        if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) {
+            $parent = $cache_id;
+            $cache_id = null;
+        }
+        if (!empty($parent) && is_array($parent)) {
+            $data = $parent;
+            $parent = null;
+        } else {
+            $data = null;
+        }
+        // default to cache_id and compile_id of Smarty object
+        $cache_id = $cache_id === null ? $this->cache_id : $cache_id;
+        $compile_id = $compile_id === null ? $this->compile_id : $compile_id;
+        // already in template cache?
+        if ($this->allow_ambiguous_resources) {
+            $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
+        } else {
+            $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id;
+        }
+        if (isset($_templateId[150])) {
+            $_templateId = sha1($_templateId);
+        }
+        if ($do_clone) {
+            if (isset($this->template_objects[$_templateId])) {
+                // return cached template object
+                $tpl = clone $this->template_objects[$_templateId];
+                $tpl->smarty = clone $tpl->smarty;
+                $tpl->parent = $parent;
+                $tpl->tpl_vars = array();
+                $tpl->config_vars = array();
+            } else {
+                $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
+            }
+        } else {
+            if (isset($this->template_objects[$_templateId])) {
+                // return cached template object
+                $tpl = $this->template_objects[$_templateId];
+                $tpl->parent = $parent;
+                $tpl->tpl_vars = array();
+                $tpl->config_vars = array();
+            } else {
+                $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
+            }
+        }
+        // fill data if present
+        if (!empty($data) && is_array($data)) {
+            // set up variable values
+            foreach ($data as $_key => $_val) {
+                $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
+            }
+        }
+        return $tpl;
+    }
+
+
+    /**
+     * Takes unknown classes and loads plugin files for them
+     * class name format: Smarty_PluginType_PluginName
+     * plugin filename format: plugintype.pluginname.php
+     *
+     * @param string $plugin_name    class plugin name to load
+     * @param bool   $check          check if already loaded
+     * @return string |boolean filepath of loaded file or false
+     */
+    public function loadPlugin($plugin_name, $check = true)
+    {
+        // if function or class exists, exit silently (already loaded)
+        if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
+            return true;
+        }
+        // Plugin name is expected to be: Smarty_[Type]_[Name]
+        $_name_parts = explode('_', $plugin_name, 3);
+        // class name must have three parts to be valid plugin
+        // count($_name_parts) < 3 === !isset($_name_parts[2])
+        if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
+            throw new SmartyException("plugin {$plugin_name} is not a valid name format");
+            return false;
+        }
+        // if type is "internal", get plugin from sysplugins
+        if (strtolower($_name_parts[1]) == 'internal') {
+            $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
+            if (file_exists($file)) {
+                require_once($file);
+                return $file;
+            } else {
+                return false;
+            }
+        }
+        // plugin filename is expected to be: [type].[name].php
+        $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
+
+        // loop through plugin dirs and find the plugin
+        foreach($this->getPluginsDir() as $_plugin_dir) {
+            $names = array(
+                $_plugin_dir . $_plugin_filename,
+                $_plugin_dir . strtolower($_plugin_filename),
+            );
+            foreach ($names as $file) {
+                if (file_exists($file)) {
+                    require_once($file);
+                    return $file;
+                }
+                if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
+                    // try PHP include_path
+                    if (($file = Smarty_Internal_Get_Include_Path::getIncludePath($file)) !== false) {
+                        require_once($file);
+                        return $file;
+                    }
+                }
+            }
+        }
+        // no plugin loaded
+        return false;
+    }
+
+    /**
+     * Compile all template files
+     *
+     * @param string $extension file extension
+     * @param bool $force_compile force all to recompile
+     * @param int $time_limit
+     * @param int $max_errors
+     * @return integer number of template files recompiled
+     */
+    public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
+    {
+        return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this);
+    }
+
+    /**
+     * Compile all config files
+     *
+     * @param string $extension file extension
+     * @param bool $force_compile force all to recompile
+     * @param int $time_limit
+     * @param int $max_errors
+     * @return integer number of template files recompiled
+     */
+    public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
+    {
+        return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this);
+    }
+
+    /**
+     * Delete compiled template file
+     *
+     * @param string $resource_name template name
+     * @param string $compile_id compile id
+     * @param integer $exp_time expiration time
+     * @return integer number of template files deleted
+     */
+    public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
+    {
+        return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
+    }
+
+
+    /**
+     * Return array of tag/attributes of all tags used by an template
+     *
+     * @param object $templae template object
+     * @return array of tag/attributes
+     */
+    public function getTags(Smarty_Internal_Template $template)
+    {
+        return Smarty_Internal_Utility::getTags($template);
+    }
+
+    /**
+     * Run installation test
+     *
+     * @param array $errors Array to write errors into, rather than outputting them
+     * @return boolean true if setup is fine, false if something is wrong
+     */
+    public function testInstall(&$errors=null)
+    {
+        return Smarty_Internal_Utility::testInstall($this, $errors);
+    }
+
+    /**
+     * Error Handler to mute expected messages
+     *
+     * @link http://php.net/set_error_handler
+     * @param integer $errno Error level
+     * @return boolean
+     */
+    public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
+    {
+        $_is_muted_directory = false;
+
+        // add the SMARTY_DIR to the list of muted directories
+        if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
+            $smarty_dir = realpath(SMARTY_DIR);
+            Smarty::$_muted_directories[SMARTY_DIR] = array(
+                'file' => $smarty_dir,
+                'length' => strlen($smarty_dir),
+            );
+        }
+
+        // walk the muted directories and test against $errfile
+        foreach (Smarty::$_muted_directories as $key => &$dir) {
+            if (!$dir) {
+                // resolve directory and length for speedy comparisons
+                $file = realpath($key);
+                $dir = array(
+                    'file' => $file,
+                    'length' => strlen($file),
+                );
+            }
+            if (!strncmp($errfile, $dir['file'], $dir['length'])) {
+                $_is_muted_directory = true;
+                break;
+            }
+        }
+
+        // pass to next error handler if this error did not occur inside SMARTY_DIR
+        // or the error was within smarty but masked to be ignored
+        if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
+            if (Smarty::$_previous_error_handler) {
+                return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Enable error handler to mute expected messages
+     *
+     * @return void
+     */
+    public static function muteExpectedErrors()
+    {
+        /*
+            error muting is done because some people implemented custom error_handlers using
+            http://php.net/set_error_handler and for some reason did not understand the following paragraph:
+
+                It is important to remember that the standard PHP error handler is completely bypassed for the
+                error types specified by error_types unless the callback function returns FALSE.
+                error_reporting() settings will have no effect and your error handler will be called regardless -
+                however you are still able to read the current value of error_reporting and act appropriately.
+                Of particular note is that this value will be 0 if the statement that caused the error was
+                prepended by the @ error-control operator.
+
+            Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
+                - @filemtime() is almost twice as fast as using an additional file_exists()
+                - between file_exists() and filemtime() a possible race condition is opened,
+                  which does not exist using the simple @filemtime() approach.
+        */
+        $error_handler = array('Smarty', 'mutingErrorHandler');
+        $previous = set_error_handler($error_handler);
+
+        // avoid dead loops
+        if ($previous !== $error_handler) {
+            Smarty::$_previous_error_handler = $previous;
+        }
+    }
+
+    /**
+     * Disable error handler muting expected messages
+     *
+     * @return void
+     */
+    public static function unmuteExpectedErrors()
+    {
+        restore_error_handler();
+    }
+}
+
+// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
+if (Smarty::$_CHARSET !== 'UTF-8') {
+    Smarty::$_UTF8_MODIFIER = '';
+}
+
+/**
+ * Smarty exception class
+ * @package Smarty
+ */
+class SmartyException extends Exception {
+}
+
+/**
+ * Smarty compiler exception class
+ * @package Smarty
+ */
+class SmartyCompilerException extends SmartyException  {
+}
+
+/**
+ * Autoloader
+ */
+function smartyAutoload($class)
+{
+    $_class = strtolower($class);
+    $_classes = array(
+        'smarty_config_source' => true,
+        'smarty_config_compiled' => true,
+        'smarty_security' => true,
+        'smarty_cacheresource' => true,
+        'smarty_cacheresource_custom' => true,
+        'smarty_cacheresource_keyvaluestore' => true,
+        'smarty_resource' => true,
+        'smarty_resource_custom' => true,
+        'smarty_resource_uncompiled' => true,
+        'smarty_resource_recompiled' => true,
+    );
+
+    if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
+        include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/SmartyBC.class.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/SmartyBC.class.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/SmartyBC.class.php	(revision 345)
@@ -0,0 +1,460 @@
+<?php
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        SmartyBC.class.php
+ * SVN:         $Id: $
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ * @package Smarty
+ */
+/**
+ * @ignore
+ */
+require(dirname(__FILE__) . '/Smarty.class.php');
+
+/**
+ * Smarty Backward Compatability Wrapper Class
+ *
+ * @package Smarty
+ */
+class SmartyBC extends Smarty {
+
+    /**
+     * Smarty 2 BC
+     * @var string
+     */
+    public $_version = self::SMARTY_VERSION;
+
+    /**
+     * Initialize new SmartyBC object
+     *
+     * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false )
+     */
+    public function __construct(array $options=array())
+    {
+        parent::__construct($options);
+        // register {php} tag
+        $this->registerPlugin('block', 'php', 'smarty_php_tag');
+    }
+
+    /**
+     * wrapper for assign_by_ref
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed  &$value  the referenced value to assign
+     */
+    public function assign_by_ref($tpl_var, &$value)
+    {
+        $this->assignByRef($tpl_var, $value);
+    }
+
+    /**
+     * wrapper for append_by_ref
+     *
+     * @param string  $tpl_var the template variable name
+     * @param mixed   &$value  the referenced value to append
+     * @param boolean $merge   flag if array elements shall be merged
+     */
+    public function append_by_ref($tpl_var, &$value, $merge = false)
+    {
+        $this->appendByRef($tpl_var, $value, $merge);
+    }
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string $tpl_var the template variable to clear
+     */
+    public function clear_assign($tpl_var)
+    {
+        $this->clearAssign($tpl_var);
+    }
+
+    /**
+     * Registers custom function to be used in templates
+     *
+     * @param string $function      the name of the template function
+     * @param string $function_impl the name of the PHP function to register
+     * @param bool   $cacheable
+     * @param mixed  $cache_attrs
+     */
+    public function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters custom function
+     *
+     * @param string $function name of template function
+     */
+    public function unregister_function($function)
+    {
+        $this->unregisterPlugin('function', $function);
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string  $object      name of template object
+     * @param object  $object_impl the referenced PHP object to register
+     * @param array   $allowed     list of allowed methods (empty = all)
+     * @param boolean $smarty_args smarty argument format, else traditional
+     * @param array   $block_functs list of methods that are block format
+     */
+    public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        settype($allowed, 'array');
+        settype($smarty_args, 'boolean');
+        $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
+    }
+
+    /**
+     * Unregisters object
+     *
+     * @param string $object name of template object
+     */
+    public function unregister_object($object)
+    {
+        $this->unregisterObject($object);
+    }
+
+    /**
+     * Registers block function to be used in templates
+     *
+     * @param string $block      name of template block
+     * @param string $block_impl PHP function to register
+     * @param bool   $cacheable
+     * @param mixed  $cache_attrs
+     */
+    public function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters block function
+     *
+     * @param string $block name of template function
+     */
+    public function unregister_block($block)
+    {
+        $this->unregisterPlugin('block', $block);
+    }
+
+    /**
+     * Registers compiler function
+     *
+     * @param string $function      name of template function
+     * @param string $function_impl name of PHP function to register
+     * @param bool   $cacheable
+     */
+    public function register_compiler_function($function, $function_impl, $cacheable=true)
+    {
+        $this->registerPlugin('compiler', $function, $function_impl, $cacheable);
+    }
+
+    /**
+     * Unregisters compiler function
+     *
+     * @param string $function name of template function
+     */
+    public function unregister_compiler_function($function)
+    {
+        $this->unregisterPlugin('compiler', $function);
+    }
+
+    /**
+     * Registers modifier to be used in templates
+     *
+     * @param string $modifier name of template modifier
+     * @param string $modifier_impl name of PHP function to register
+     */
+    public function register_modifier($modifier, $modifier_impl)
+    {
+        $this->registerPlugin('modifier', $modifier, $modifier_impl);
+    }
+
+    /**
+     * Unregisters modifier
+     *
+     * @param string $modifier name of template modifier
+     */
+    public function unregister_modifier($modifier)
+    {
+        $this->unregisterPlugin('modifier', $modifier);
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type      name of resource
+     * @param array  $functions array of functions to handle resource
+     */
+    public function register_resource($type, $functions)
+    {
+        $this->registerResource($type, $functions);
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource
+     */
+    public function unregister_resource($type)
+    {
+        $this->unregisterResource($type);
+    }
+
+    /**
+     * Registers a prefilter function to apply
+     * to a template before compiling
+     *
+     * @param callable $function
+     */
+    public function register_prefilter($function)
+    {
+        $this->registerFilter('pre', $function);
+    }
+
+    /**
+     * Unregisters a prefilter function
+     *
+     * @param callable $function
+     */
+    public function unregister_prefilter($function)
+    {
+        $this->unregisterFilter('pre', $function);
+    }
+
+    /**
+     * Registers a postfilter function to apply
+     * to a compiled template after compilation
+     *
+     * @param callable $function
+     */
+    public function register_postfilter($function)
+    {
+        $this->registerFilter('post', $function);
+    }
+
+    /**
+     * Unregisters a postfilter function
+     *
+     * @param callable $function
+     */
+    public function unregister_postfilter($function)
+    {
+        $this->unregisterFilter('post', $function);
+    }
+
+    /**
+     * Registers an output filter function to apply
+     * to a template output
+     *
+     * @param callable $function
+     */
+    public function register_outputfilter($function)
+    {
+        $this->registerFilter('output', $function);
+    }
+
+    /**
+     * Unregisters an outputfilter function
+     *
+     * @param callable $function
+     */
+    public function unregister_outputfilter($function)
+    {
+        $this->unregisterFilter('output', $function);
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     */
+    public function load_filter($type, $name)
+    {
+        $this->loadFilter($type, $name);
+    }
+
+    /**
+     * clear cached content for the given template and cache id
+     *
+     * @param string $tpl_file   name of template file
+     * @param string $cache_id   name of cache_id
+     * @param string $compile_id name of compile_id
+     * @param string $exp_time   expiration time
+     * @return boolean
+     */
+    public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+    {
+        return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
+    }
+
+    /**
+     * clear the entire contents of cache (all templates)
+     *
+     * @param string $exp_time expire time
+     * @return boolean
+     */
+    public function clear_all_cache($exp_time = null)
+    {
+        return $this->clearCache(null, null, null, $exp_time);
+    }
+
+    /**
+     * test to see if valid cache exists for this template
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return boolean
+     */
+    public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+    {
+        return $this->isCached($tpl_file, $cache_id, $compile_id);
+    }
+
+    /**
+     * clear all the assigned template variables.
+     */
+    public function clear_all_assign()
+    {
+        $this->clearAllAssign();
+    }
+
+    /**
+     * clears compiled version of specified template resource,
+     * or all compiled template files if one is not specified.
+     * This function is for advanced use only, not normally needed.
+     *
+     * @param string $tpl_file
+     * @param string $compile_id
+     * @param string $exp_time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+    {
+        return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
+    }
+
+    /**
+     * Checks whether requested template exists.
+     *
+     * @param string $tpl_file
+     * @return boolean
+     */
+    public function template_exists($tpl_file)
+    {
+        return $this->templateExists($tpl_file);
+    }
+
+    /**
+     * Returns an array containing template variables
+     *
+     * @param string $name
+     * @return array
+     */
+    public function get_template_vars($name=null)
+    {
+        return $this->getTemplateVars($name);
+    }
+
+    /**
+     * Returns an array containing config variables
+     *
+     * @param string $name
+     * @return array
+     */
+    public function get_config_vars($name=null)
+    {
+        return $this->getConfigVars($name);
+    }
+
+    /**
+     * load configuration values
+     *
+     * @param string $file
+     * @param string $section
+     * @param string $scope
+     */
+    public function config_load($file, $section = null, $scope = 'global')
+    {
+        $this->ConfigLoad($file, $section, $scope);
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name
+     * @return object
+     */
+    public function get_registered_object($name)
+    {
+        return $this->getRegisteredObject($name);
+    }
+
+    /**
+     * clear configuration values
+     *
+     * @param string $var
+     */
+    public function clear_config($var = null)
+    {
+        $this->clearConfig($var);
+    }
+
+    /**
+     * trigger Smarty error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     */
+    public function trigger_error($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Smarty error: $error_msg", $error_type);
+    }
+
+}
+
+/**
+ * Smarty {php}{/php} block function
+ *
+ * @param array   $params   parameter list
+ * @param string  $content  contents of the block
+ * @param object  $template template object
+ * @param boolean &$repeat  repeat flag
+ * @return string content re-formatted
+ */
+function smarty_php_tag($params, $content, $template, &$repeat)
+{
+    eval($content);
+    return '';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/debug.tpl
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/debug.tpl	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/debug.tpl	(revision 345)
@@ -0,0 +1,133 @@
+{capture name='_smarty_debug' assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+    <title>Smarty Debug Console</title>
+<style type="text/css">
+{literal}
+body, h1, h2, td, th, p {
+    font-family: sans-serif;
+    font-weight: normal;
+    font-size: 0.9em;
+    margin: 1px;
+    padding: 0;
+}
+
+h1 {
+    margin: 0;
+    text-align: left;
+    padding: 2px;
+    background-color: #f0c040;
+    color:  black;
+    font-weight: bold;
+    font-size: 1.2em;
+ }
+
+h2 {
+    background-color: #9B410E;
+    color: white;
+    text-align: left;
+    font-weight: bold;
+    padding: 2px;
+    border-top: 1px solid black;
+}
+
+body {
+    background: black; 
+}
+
+p, table, div {
+    background: #f0ead8;
+} 
+
+p {
+    margin: 0;
+    font-style: italic;
+    text-align: center;
+}
+
+table {
+    width: 100%;
+}
+
+th, td {
+    font-family: monospace;
+    vertical-align: top;
+    text-align: left;
+    width: 50%;
+}
+
+td {
+    color: green;
+}
+
+.odd {
+    background-color: #eeeeee;
+}
+
+.even {
+    background-color: #fafafa;
+}
+
+.exectime {
+    font-size: 0.8em;
+    font-style: italic;
+}
+
+#table_assigned_vars th {
+    color: blue;
+}
+
+#table_config_vars th {
+    color: maroon;
+}
+{/literal}
+</style>
+</head>
+<body>
+
+<h1>Smarty Debug Console  -  {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
+
+{if !empty($template_data)}
+<h2>included templates &amp; config files (load time in seconds)</h2>
+
+<div>
+{foreach $template_data as $template}
+  <font color=brown>{$template.name}</font>
+  <span class="exectime">
+   (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
+  </span>
+  <br>
+{/foreach}
+</div>
+{/if}
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+    {foreach $assigned_vars as $vars}
+       <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">   
+       <th>${$vars@key|escape:'html'}</th>
+       <td>{$vars|debug_print_var nofilter}</td></tr>
+    {/foreach}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+    {foreach $config_vars as $vars}
+       <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">   
+       <th>{$vars@key|escape:'html'}</th>
+       <td>{$vars|debug_print_var nofilter}</td></tr>
+    {/foreach}
+
+</table>
+</body>
+</html>
+{/capture}
+<script type="text/javascript">
+{$id = $template_name|default:''|md5}
+    _smarty_console = window.open("","console{$id}","width=680,height=600,resizable,scrollbars=yes");
+    _smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
+    _smarty_console.document.close();
+</script>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/block.textformat.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/block.textformat.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/block.textformat.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Smarty plugin to format text blocks
+ *
+ * @package Smarty
+ * @subpackage PluginsBlock
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type:     block function<br>
+ * Name:     textformat<br>
+ * Purpose:  format text a certain way with preset styles
+ *           or custom wrap/indent settings<br>
+ * Params:
+ * <pre>
+ * - style         - string (email)
+ * - indent        - integer (0)
+ * - wrap          - integer (80)
+ * - wrap_char     - string ("\n")
+ * - indent_char   - string (" ")
+ * - wrap_boundary - boolean (true)
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
+ *       (Smarty online manual)
+ * @param array                    $params   parameters
+ * @param string                   $content  contents of the block
+ * @param Smarty_Internal_Template $template template object
+ * @param boolean                  &$repeat  repeat flag
+ * @return string content re-formatted
+ * @author Monte Ohrt <monte at ohrt dot com>
+ */
+function smarty_block_textformat($params, $content, $template, &$repeat)
+{
+    if (is_null($content)) {
+        return;
+    }
+
+    $style = null;
+    $indent = 0;
+    $indent_first = 0;
+    $indent_char = ' ';
+    $wrap = 80;
+    $wrap_char = "\n";
+    $wrap_cut = false;
+    $assign = null;
+
+    foreach ($params as $_key => $_val) {
+        switch ($_key) {
+            case 'style':
+            case 'indent_char':
+            case 'wrap_char':
+            case 'assign':
+                $$_key = (string)$_val;
+                break;
+
+            case 'indent':
+            case 'indent_first':
+            case 'wrap':
+                $$_key = (int)$_val;
+                break;
+
+            case 'wrap_cut':
+                $$_key = (bool)$_val;
+                break;
+
+            default:
+                trigger_error("textformat: unknown attribute '$_key'");
+        }
+    }
+
+    if ($style == 'email') {
+        $wrap = 72;
+    }
+    // split into paragraphs
+    $_paragraphs = preg_split('![\r\n]{2}!', $content);
+    $_output = '';
+
+
+    foreach ($_paragraphs as &$_paragraph) {
+        if (!$_paragraph) {
+            continue;
+        }
+        // convert mult. spaces & special chars to single space
+        $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph);
+        // indent first line
+        if ($indent_first > 0) {
+            $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
+        }
+        // wordwrap sentences
+        if (Smarty::$_MBSTRING) {
+            require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
+            $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
+        } else {
+            $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
+        }
+        // indent lines
+        if ($indent > 0) {
+            $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
+        }
+    }
+    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+    
+    if ($assign) {
+        $template->assign($assign, $_output);
+    } else {
+        return $_output;
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.counter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.counter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.counter.php	(revision 345)
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type:     function<br>
+ * Name:     counter<br>
+ * Purpose:  print out a counter value
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
+ *       (Smarty online manual)
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string|null
+ */
+function smarty_function_counter($params, $template)
+{
+    static $counters = array();
+
+    $name = (isset($params['name'])) ? $params['name'] : 'default';
+    if (!isset($counters[$name])) {
+        $counters[$name] = array(
+            'start'=>1,
+            'skip'=>1,
+            'direction'=>'up',
+            'count'=>1
+            );
+    }
+    $counter =& $counters[$name];
+
+    if (isset($params['start'])) {
+        $counter['start'] = $counter['count'] = (int)$params['start'];
+    }
+
+    if (!empty($params['assign'])) {
+        $counter['assign'] = $params['assign'];
+    }
+
+    if (isset($counter['assign'])) {
+        $template->assign($counter['assign'], $counter['count']);
+    }
+    
+    if (isset($params['print'])) {
+        $print = (bool)$params['print'];
+    } else {
+        $print = empty($counter['assign']);
+    }
+
+    if ($print) {
+        $retval = $counter['count'];
+    } else {
+        $retval = null;
+    }
+
+    if (isset($params['skip'])) {
+        $counter['skip'] = $params['skip'];
+    }
+    
+    if (isset($params['direction'])) {
+        $counter['direction'] = $params['direction'];
+    }
+
+    if ($counter['direction'] == "down")
+        $counter['count'] -= $counter['skip'];
+    else
+        $counter['count'] += $counter['skip'];
+    
+    return $retval;
+    
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.cycle.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.cycle.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.cycle.php	(revision 345)
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type:     function<br>
+ * Name:     cycle<br>
+ * Date:     May 3, 2002<br>
+ * Purpose:  cycle through given values<br>
+ * Params:
+ * <pre>
+ * - name      - name of cycle (optional)
+ * - values    - comma separated list of values to cycle, or an array of values to cycle
+ *               (this can be left out for subsequent calls)
+ * - reset     - boolean - resets given var to true
+ * - print     - boolean - print var or not. default is true
+ * - advance   - boolean - whether or not to advance the cycle
+ * - delimiter - the value delimiter, default is ","
+ * - assign    - boolean, assigns to template var instead of printed.
+ * </pre>
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version  1.3
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string|null
+ */
+
+function smarty_function_cycle($params, $template)
+{
+    static $cycle_vars;
+
+    $name = (empty($params['name'])) ? 'default' : $params['name'];
+    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+
+    if (!isset($params['values'])) {
+        if(!isset($cycle_vars[$name]['values'])) {
+            trigger_error("cycle: missing 'values' parameter");
+            return;
+        }
+    } else {
+        if(isset($cycle_vars[$name]['values'])
+            && $cycle_vars[$name]['values'] != $params['values'] ) {
+            $cycle_vars[$name]['index'] = 0;
+        }
+        $cycle_vars[$name]['values'] = $params['values'];
+    }
+
+    if (isset($params['delimiter'])) {
+        $cycle_vars[$name]['delimiter'] = $params['delimiter'];
+    } elseif (!isset($cycle_vars[$name]['delimiter'])) {
+        $cycle_vars[$name]['delimiter'] = ',';
+    }
+
+    if(is_array($cycle_vars[$name]['values'])) {
+        $cycle_array = $cycle_vars[$name]['values'];
+    } else {
+        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+    }
+
+    if(!isset($cycle_vars[$name]['index']) || $reset ) {
+        $cycle_vars[$name]['index'] = 0;
+    }
+
+    if (isset($params['assign'])) {
+        $print = false;
+        $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+    }
+
+    if($print) {
+        $retval = $cycle_array[$cycle_vars[$name]['index']];
+    } else {
+        $retval = null;
+    }
+
+    if($advance) {
+        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+            $cycle_vars[$name]['index'] = 0;
+        } else {
+            $cycle_vars[$name]['index']++;
+        }
+    }
+
+    return $retval;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.fetch.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.fetch.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.fetch.php	(revision 345)
@@ -0,0 +1,214 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type:     function<br>
+ * Name:     fetch<br>
+ * Purpose:  fetch file, web or ftp data and display results
+ *
+ * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
+ */
+function smarty_function_fetch($params, $template)
+{
+    if (empty($params['file'])) {
+        trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE);
+        return;
+    }
+    
+    // strip file protocol
+    if (stripos($params['file'], 'file://') === 0) {
+        $params['file'] = substr($params['file'], 7);
+    }
+    
+    $protocol = strpos($params['file'], '://');
+    if ($protocol !== false) {
+        $protocol = strtolower(substr($params['file'], 0, $protocol));
+    }
+    
+    if (isset($template->smarty->security_policy)) {
+        if ($protocol) {
+            // remote resource (or php stream, âŠ)
+            if(!$template->smarty->security_policy->isTrustedUri($params['file'])) {
+                return;
+            }
+        } else {
+            // local file
+            if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
+                return;
+            }
+        }
+    }
+
+    $content = '';
+    if ($protocol == 'http') {
+        // http fetch
+        if($uri_parts = parse_url($params['file'])) {
+            // set defaults
+            $host = $server_name = $uri_parts['host'];
+            $timeout = 30;
+            $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+            $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION;
+            $referer = "";
+            $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+            $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+            $_is_proxy = false;
+            if(empty($uri_parts['port'])) {
+                $port = 80;
+            } else {
+                $port = $uri_parts['port'];
+            }
+            if(!empty($uri_parts['user'])) {
+                $user = $uri_parts['user'];
+            }
+            if(!empty($uri_parts['pass'])) {
+                $pass = $uri_parts['pass'];
+            }
+            // loop through parameters, setup headers
+            foreach($params as $param_key => $param_value) {
+                switch($param_key) {
+                    case "file":
+                    case "assign":
+                    case "assign_headers":
+                        break;
+                    case "user":
+                        if(!empty($param_value)) {
+                            $user = $param_value;
+                        }
+                        break;
+                    case "pass":
+                        if(!empty($param_value)) {
+                            $pass = $param_value;
+                        }
+                        break;
+                    case "accept":
+                        if(!empty($param_value)) {
+                            $accept = $param_value;
+                        }
+                        break;
+                    case "header":
+                        if(!empty($param_value)) {
+                            if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+                                trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE);
+                                return;
+                            } else {
+                                $extra_headers[] = $param_value;
+                            }
+                        }
+                        break;
+                    case "proxy_host":
+                        if(!empty($param_value)) {
+                            $proxy_host = $param_value;
+                        }
+                        break;
+                    case "proxy_port":
+                        if(!preg_match('!\D!', $param_value)) {
+                            $proxy_port = (int) $param_value;
+                        } else {
+                            trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
+                            return;
+                        }
+                        break;
+                    case "agent":
+                        if(!empty($param_value)) {
+                            $agent = $param_value;
+                        }
+                        break;
+                    case "referer":
+                        if(!empty($param_value)) {
+                            $referer = $param_value;
+                        }
+                        break;
+                    case "timeout":
+                        if(!preg_match('!\D!', $param_value)) {
+                            $timeout = (int) $param_value;
+                        } else {
+                            trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
+                            return;
+                        }
+                        break;
+                    default:
+                        trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE);
+                        return;
+                }
+            }
+            if(!empty($proxy_host) && !empty($proxy_port)) {
+                $_is_proxy = true;
+                $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+            } else {
+                $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+            }
+
+            if(!$fp) {
+                trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE);
+                return;
+            } else {
+                if($_is_proxy) {
+                    fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+                } else {
+                    fputs($fp, "GET $uri HTTP/1.0\r\n");
+                }
+                if(!empty($host)) {
+                    fputs($fp, "Host: $host\r\n");
+                }
+                if(!empty($accept)) {
+                    fputs($fp, "Accept: $accept\r\n");
+                }
+                if(!empty($agent)) {
+                    fputs($fp, "User-Agent: $agent\r\n");
+                }
+                if(!empty($referer)) {
+                    fputs($fp, "Referer: $referer\r\n");
+                }
+                if(isset($extra_headers) && is_array($extra_headers)) {
+                    foreach($extra_headers as $curr_header) {
+                        fputs($fp, $curr_header."\r\n");
+                    }
+                }
+                if(!empty($user) && !empty($pass)) {
+                    fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+                }
+
+                fputs($fp, "\r\n");
+                while(!feof($fp)) {
+                    $content .= fgets($fp,4096);
+                }
+                fclose($fp);
+                $csplit = preg_split("!\r\n\r\n!",$content,2);
+
+                $content = $csplit[1];
+
+                if(!empty($params['assign_headers'])) {
+                    $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0]));
+                }
+            }
+        } else {
+            trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE);
+            return;
+        }
+    } else {
+        $content = @file_get_contents($params['file']);
+        if ($content === false) {
+            throw new SmartyException("{fetch} cannot read resource '" . $params['file'] ."'");
+        }
+    }
+
+    if (!empty($params['assign'])) {
+        $template->assign($params['assign'], $content);
+    } else {
+        return $content;
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_checkboxes.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_checkboxes.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_checkboxes.php	(revision 345)
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File:       function.html_checkboxes.php<br>
+ * Type:       function<br>
+ * Name:       html_checkboxes<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of checkbox input types<br>
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * Params:
+ * <pre>
+ * - name       (optional) - string default "checkbox"
+ * - values     (required) - array
+ * - options    (optional) - associative array
+ * - checked    (optional) - array default not set
+ * - separator  (optional) - ie <br> or &nbsp;
+ * - output     (optional) - the output next to each checkbox
+ * - assign     (optional) - assign the output as an array to this variable
+ * - escape     (optional) - escape the content (not value), defaults to true
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array $params parameters
+ * @param object $template template object
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, $template)
+{
+    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+    $name = 'checkbox';
+    $values = null;
+    $options = null;
+    $selected = array();
+    $separator = '';
+    $escape = true;
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string) $_val;
+                break;
+
+            case 'escape':
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool) $_val;
+                break;
+
+            case 'options':
+                $$_key = (array) $_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array) $_val);
+                break;
+
+            case 'checked':
+            case 'selected':
+                if (is_array($_val)) {
+                    $selected = array();
+                    foreach ($_val as $_sel) {
+                        if (is_object($_sel)) {
+                            if (method_exists($_sel, "__toString")) {
+                                $_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
+                            } else {
+                                trigger_error("html_checkboxes: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE);
+                                continue;
+                            }
+                        } else {
+                            $_sel = smarty_function_escape_special_chars((string) $_sel);
+                        }
+                        $selected[$_sel] = true;
+                    }
+                } elseif (is_object($_val)) {
+                    if (method_exists($_val, "__toString")) {
+                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
+                    } else {
+                        trigger_error("html_checkboxes: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
+                    }
+                } else {
+                    $selected = smarty_function_escape_special_chars((string) $_val);
+                }
+                break;
+
+            case 'checkboxes':
+                trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array) $_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = array();
+
+    if (isset($options)) {
+        foreach ($options as $_key=>$_val) {
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+        }
+    } else {
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+        }
+    }
+
+    if(!empty($params['assign'])) {
+        $template->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n", $_html_result);
+    }
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) {
+    $_output = '';
+    
+    if (is_object($value)) {
+        if (method_exists($value, "__toString")) {
+            $value = (string) $value->__toString();
+        } else {
+            trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
+            return '';
+        }
+    } else {
+        $value = (string) $value;
+    }
+    
+    if (is_object($output)) {
+        if (method_exists($output, "__toString")) {
+            $output = (string) $output->__toString();
+        } else {
+            trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE);
+            return '';
+        }
+    } else {
+        $output = (string) $output;
+    }
+    
+    if ($labels) {
+        if ($label_ids) {
+            $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
+            $_output .= '<label for="' . $_id . '">';
+        } else {
+            $_output .= '<label>';
+        } 
+    }
+    
+    $name = smarty_function_escape_special_chars($name);
+    $value = smarty_function_escape_special_chars($value);
+    if ($escape) {
+        $output = smarty_function_escape_special_chars($output);
+    }
+    
+    $_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
+    
+    if ($labels && $label_ids) {
+        $_output .= ' id="' . $_id . '"';
+    }
+    
+    if (is_array($selected)) {
+        if (isset($selected[$value])) {
+            $_output .= ' checked="checked"';
+        }
+    } elseif ($value === $selected) {
+        $_output .= ' checked="checked"';
+    }
+    
+    $_output .= $extra . ' />' . $output;
+    if ($labels) {
+        $_output .= '</label>';
+    }
+    
+    $_output .=  $separator;
+    return $_output;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_image.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_image.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_image.php	(revision 345)
@@ -0,0 +1,159 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_image} function plugin
+ * 
+ * Type:     function<br>
+ * Name:     html_image<br>
+ * Date:     Feb 24, 2003<br>
+ * Purpose:  format HTML tags for the image<br>
+ * Examples: {html_image file="/images/masthead.gif"}<br>
+ * Output:   <img src="/images/masthead.gif" width=400 height=23><br>
+ * Params:
+ * <pre>
+ * - file        - (required) - file (and path) of image
+ * - height      - (optional) - image height (default actual height)
+ * - width       - (optional) - image width (default actual width)
+ * - basedir     - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
+ * - path_prefix - prefix for path output (optional, default empty)
+ * </pre>
+ * 
+ * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
+ *      (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @author credits to Duda <duda@big.hu> 
+ * @version 1.0
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string 
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, $template)
+{
+    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+ 
+    $alt = '';
+    $file = '';
+    $height = '';
+    $width = '';
+    $extra = '';
+    $prefix = '';
+    $suffix = '';
+    $path_prefix = '';
+    $basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
+    foreach($params as $_key => $_val) {
+        switch ($_key) {
+            case 'file':
+            case 'height':
+            case 'width':
+            case 'dpi':
+            case 'path_prefix':
+            case 'basedir':
+                $$_key = $_val;
+                break;
+
+            case 'alt':
+                if (!is_array($_val)) {
+                    $$_key = smarty_function_escape_special_chars($_val);
+                } else {
+                    throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                } 
+                break;
+
+            case 'link':
+            case 'href':
+                $prefix = '<a href="' . $_val . '">';
+                $suffix = '</a>';
+                break;
+
+            default:
+                if (!is_array($_val)) {
+                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+                } else {
+                    throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                } 
+                break;
+        } 
+    } 
+
+    if (empty($file)) {
+        trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+        return;
+    } 
+
+    if ($file[0] == '/') {
+        $_image_path = $basedir . $file;
+    } else {
+        $_image_path = $file;
+    }
+    
+    // strip file protocol
+    if (stripos($params['file'], 'file://') === 0) {
+        $params['file'] = substr($params['file'], 7);
+    }
+    
+    $protocol = strpos($params['file'], '://');
+    if ($protocol !== false) {
+        $protocol = strtolower(substr($params['file'], 0, $protocol));
+    }
+    
+    if (isset($template->smarty->security_policy)) {
+        if ($protocol) {
+            // remote resource (or php stream, âŠ)
+            if(!$template->smarty->security_policy->isTrustedUri($params['file'])) {
+                return;
+            }
+        } else {
+            // local file
+            if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
+                return;
+            }
+        }
+    }
+
+    if (!isset($params['width']) || !isset($params['height'])) {
+        // FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
+        if (!$_image_data = @getimagesize($_image_path)) {
+            if (!file_exists($_image_path)) {
+                trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+                return;
+            } else if (!is_readable($_image_path)) {
+                trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+                return;
+            } else {
+                trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+                return;
+            } 
+        }
+
+        if (!isset($params['width'])) {
+            $width = $_image_data[0];
+        } 
+        if (!isset($params['height'])) {
+            $height = $_image_data[1];
+        } 
+    } 
+
+    if (isset($params['dpi'])) {
+        if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) {
+            // FIXME: (rodneyrehm) wrong dpi assumption
+            // don't know who thought this upâŠ even if it was true in 1998, it's definitely wrong in 2011.
+            $dpi_default = 72;
+        } else {
+            $dpi_default = 96;
+        } 
+        $_resize = $dpi_default / $params['dpi'];
+        $width = round($width * $_resize);
+        $height = round($height * $_resize);
+    } 
+
+    return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_options.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_options.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_options.php	(revision 345)
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_options} function plugin
+ * 
+ * Type:     function<br>
+ * Name:     html_options<br>
+ * Purpose:  Prints the list of <option> tags generated from
+ *           the passed parameters<br>
+ * Params:
+ * <pre>
+ * - name       (optional) - string default "select"
+ * - values     (required) - if no options supplied) - array
+ * - options    (required) - if no values supplied) - associative array
+ * - selected   (optional) - string default not set
+ * - output     (required) - if not options supplied) - array
+ * - id         (optional) - string default not set
+ * - class      (optional) - string default not set
+ * </pre>
+ * 
+ * @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
+ *      (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string 
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, $template)
+{
+    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+    $name = null;
+    $values = null;
+    $options = null;
+    $selected = null;
+    $output = null;
+    $id = null;
+    $class = null;
+
+    $extra = '';
+
+    foreach ($params as $_key => $_val) {
+        switch ($_key) {
+            case 'name':
+            case 'class':
+            case 'id':
+                $$_key = (string) $_val;
+                break;
+
+            case 'options':
+                $options = (array) $_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array) $_val);
+                break;
+
+            case 'selected':
+                if (is_array($_val)) {
+                    $selected = array();
+                    foreach ($_val as $_sel) {
+                        if (is_object($_sel)) {
+                            if (method_exists($_sel, "__toString")) {
+                                $_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
+                            } else {
+                                trigger_error("html_options: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE);
+                                continue;
+                            }
+                        } else {
+                            $_sel = smarty_function_escape_special_chars((string) $_sel);
+                        }
+                        $selected[$_sel] = true;
+                    }
+                } elseif (is_object($_val)) {
+                    if (method_exists($_val, "__toString")) {
+                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
+                    } else {
+                        trigger_error("html_options: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
+                    }
+                } else {
+                    $selected = smarty_function_escape_special_chars((string) $_val);
+                }
+                break;
+
+            default:
+                if (!is_array($_val)) {
+                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+                } else {
+                    trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                } 
+                break;
+        } 
+    }
+
+    if (!isset($options) && !isset($values)) {
+        /* raise error here? */
+        return '';
+    }
+
+    $_html_result = '';
+    $_idx = 0;
+
+    if (isset($options)) {
+        foreach ($options as $_key => $_val) {
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
+        }
+    } else {
+        foreach ($values as $_i => $_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
+        } 
+    }
+
+    if (!empty($name)) {
+        $_html_class = !empty($class) ? ' class="'.$class.'"' : '';
+        $_html_id = !empty($id) ? ' id="'.$id.'"' : '';
+        $_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+    } 
+
+    return $_html_result;
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx)
+{
+    if (!is_array($value)) {
+        $_key = smarty_function_escape_special_chars($key);
+        $_html_result = '<option value="' . $_key . '"';
+        if (is_array($selected)) {
+            if (isset($selected[$_key])) {
+                $_html_result .= ' selected="selected"';
+            }
+        } elseif ($_key === $selected) {
+            $_html_result .= ' selected="selected"';
+        }
+        $_html_class = !empty($class) ? ' class="'.$class.' option"' : '';
+        $_html_id = !empty($id) ? ' id="'.$id.'-'.$idx.'"' : '';
+        if (is_object($value)) {
+            if (method_exists($value, "__toString")) {
+                $value = smarty_function_escape_special_chars((string) $value->__toString());
+            } else {
+                trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
+                return '';
+            }
+        }
+        $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
+        $idx++;
+    } else {
+        $_idx = 0;
+        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id.'-'.$idx) : null, $class, $_idx);
+        $idx++;
+    }
+    return $_html_result;
+} 
+
+function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx)
+{
+    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+    foreach ($values as $key => $value) {
+        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
+    } 
+    $optgroup_html .= "</optgroup>\n";
+    return $optgroup_html;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_radios.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_radios.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_radios.php	(revision 345)
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_radios} function plugin
+ * 
+ * File:       function.html_radios.php<br>
+ * Type:       function<br>
+ * Name:       html_radios<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of radio input types<br>
+ * Params:
+ * <pre>
+ * - name       (optional) - string default "radio"
+ * - values     (required) - array
+ * - options    (required) - associative array
+ * - checked    (optional) - array default not set
+ * - separator  (optional) - ie <br> or &nbsp;
+ * - output     (optional) - the output next to each radio button
+ * - assign     (optional) - assign the output as an array to this variable
+ * - escape     (optional) - escape the content (not value), defaults to true
+ * </pre>
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * 
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ *      (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com> 
+ * @author credits to Monte Ohrt <monte at ohrt dot com> 
+ * @version 1.0
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string 
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, $template)
+{
+    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+    $name = 'radio';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $escape = true;
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch ($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string) $_val;
+                break;
+
+            case 'checked':
+            case 'selected':
+                if (is_array($_val)) {
+                    trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+                } elseif (is_object($_val)) {
+                    if (method_exists($_val, "__toString")) {
+                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
+                    } else {
+                        trigger_error("html_radios: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
+                    }
+                } else {
+                    $selected = (string) $_val;
+                } 
+                break;
+
+            case 'escape':
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool) $_val;
+                break;
+
+            case 'options':
+                $$_key = (array) $_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array) $_val);
+                break;
+
+            case 'radios':
+                trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array) $_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if (!is_array($_val)) {
+                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+                } else {
+                    trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                } 
+                break;
+        } 
+    } 
+
+    if (!isset($options) && !isset($values)) {
+        /* raise error here? */
+        return '';
+    }
+
+    $_html_result = array();
+
+    if (isset($options)) {
+        foreach ($options as $_key => $_val) {
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+        }
+    } else {
+        foreach ($values as $_i => $_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+        } 
+    } 
+
+    if (!empty($params['assign'])) {
+        $template->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n", $_html_result);
+    } 
+} 
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape)
+{
+    $_output = '';
+    
+    if (is_object($value)) {
+        if (method_exists($value, "__toString")) {
+            $value = (string) $value->__toString();
+        } else {
+            trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
+            return '';
+        }
+    } else {
+        $value = (string) $value;
+    }
+    
+    if (is_object($output)) {
+        if (method_exists($output, "__toString")) {
+            $output = (string) $output->__toString();
+        } else {
+            trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE);
+            return '';
+        }
+    } else {
+        $output = (string) $output;
+    }
+    
+    if ($labels) {
+        if ($label_ids) {
+            $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
+            $_output .= '<label for="' . $_id . '">';
+        } else {
+            $_output .= '<label>';
+        } 
+    }
+    
+    $name = smarty_function_escape_special_chars($name);
+    $value = smarty_function_escape_special_chars($value);
+    if ($escape) {
+        $output = smarty_function_escape_special_chars($output);
+    }
+    
+    $_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
+
+    if ($labels && $label_ids) {
+        $_output .= ' id="' . $_id . '"';
+    }
+
+    if ($value === $selected) {
+        $_output .= ' checked="checked"';
+    }
+    
+    $_output .= $extra . ' />' . $output;
+    if ($labels) {
+        $_output .= '</label>';
+    }
+    
+    $_output .= $separator;
+    return $_output;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_date.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_date.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_date.php	(revision 345)
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+
+/**
+ * Smarty {html_select_date} plugin
+ * 
+ * Type:     function<br>
+ * Name:     html_select_date<br>
+ * Purpose:  Prints the dropdowns for date selection.
+ * 
+ * ChangeLog:
+ * <pre>
+ *            - 1.0 initial release
+ *            - 1.1 added support for +/- N syntax for begin
+ *              and end year values. (Monte)
+ *            - 1.2 added support for yyyy-mm-dd syntax for
+ *              time value. (Jan Rosier)
+ *            - 1.3 added support for choosing format for
+ *              month values (Gary Loescher)
+ *            - 1.3.1 added support for choosing format for
+ *              day values (Marcus Bointon)
+ *            - 1.3.2 support negative timestamps, force year
+ *              dropdown to include given date unless explicitly set (Monte)
+ *            - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ *              of 0000-00-00 dates (cybot, boots)
+ *            - 2.0 complete rewrite for performance,  
+ *              added attributes month_names, *_id
+ * </pre>
+ * 
+ * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
+ *      (Smarty online manual)
+ * @version 2.0
+ * @author Andrei Zmievski 
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @author Rodney Rehm
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string 
+ */
+function smarty_function_html_select_date($params, $template)
+{
+    // generate timestamps used for month names only
+    static $_month_timestamps = null;
+    static $_current_year = null;
+    if ($_month_timestamps === null) {
+        $_current_year = date('Y');
+        $_month_timestamps = array();
+        for ($i = 1; $i <= 12; $i++) {
+            $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
+        }
+    }
+
+    /* Default values. */
+    $prefix = "Date_";
+    $start_year = null;
+    $end_year = null;
+    $display_days = true;
+    $display_months = true;
+    $display_years = true;
+    $month_format = "%B";
+    /* Write months as numbers by default  GL */
+    $month_value_format = "%m";
+    $day_format = "%02d";
+    /* Write day values using this format MB */
+    $day_value_format = "%d";
+    $year_as_text = false;
+    /* Display years in reverse order? Ie. 2000,1999,.... */
+    $reverse_years = false;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Day]",
+       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+    $field_array = null;
+    /* <select size>'s of the different <select> tags.
+       If not set, uses default dropdown. */
+    $day_size = null;
+    $month_size = null;
+    $year_size = null;
+    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+       An example might be in the template: all_extra ='class ="foo"'. */
+    $all_extra = null;
+    /* Separate attributes for the tags. */
+    $day_extra = null;
+    $month_extra = null;
+    $year_extra = null;
+    /* Order in which to display the fields.
+       "D" -> day, "M" -> month, "Y" -> year. */
+    $field_order = 'MDY';
+    /* String printed between the different fields. */
+    $field_separator = "\n";
+    $option_separator = "\n";
+    $time = null;
+    // $all_empty = null;
+    // $day_empty = null;
+    // $month_empty = null;
+    // $year_empty = null;
+    $extra_attrs = '';
+    $all_id = null;
+    $day_id = null;
+    $month_id = null;
+    $year_id = null;
+
+    foreach ($params as $_key => $_value) {
+        switch ($_key) {
+            case 'time':
+                if (!is_array($_value) && $_value !== null) {
+                    $time = smarty_make_timestamp($_value);
+                }
+                break;
+                
+            case 'month_names':
+                if (is_array($_value) && count($_value) == 12) {
+                    $$_key = $_value;
+                } else {
+                    trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
+                }
+                break;
+                
+            case 'prefix':
+            case 'field_array':
+            case 'start_year':
+            case 'end_year':
+            case 'day_format':
+            case 'day_value_format':
+            case 'month_format':
+            case 'month_value_format':
+            case 'day_size':
+            case 'month_size':
+            case 'year_size':
+            case 'all_extra':
+            case 'day_extra':
+            case 'month_extra':
+            case 'year_extra':
+            case 'field_order':
+            case 'field_separator':
+            case 'option_separator':
+            case 'all_empty':
+            case 'month_empty':
+            case 'day_empty':
+            case 'year_empty':
+            case 'all_id':
+            case 'month_id':
+            case 'day_id':
+            case 'year_id':
+                $$_key = (string)$_value;
+                break;
+
+            case 'display_days':
+            case 'display_months':
+            case 'display_years':
+            case 'year_as_text':
+            case 'reverse_years':
+                $$_key = (bool)$_value;
+                break;
+
+            default:
+                if (!is_array($_value)) {
+                    $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
+                } else {
+                    trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                } 
+                break;
+        } 
+    }
+    
+    // Note: date() is faster than strftime()
+    // Note: explode(date()) is faster than date() date() date()
+    if (isset($params['time']) && is_array($params['time'])) {
+        if (isset($params['time'][$prefix . 'Year'])) {
+            // $_REQUEST[$field_array] given
+            foreach (array('Y' => 'Year',  'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
+                $_variableName = '_' . strtolower($_elementName);
+                $$_variableName = isset($params['time'][$prefix . $_elementName])
+                    ? $params['time'][$prefix . $_elementName]
+                    : date($_elementKey);
+            }
+            $time = mktime(0, 0, 0, $_month, $_day, $_year);
+        } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
+            // $_REQUEST given
+            foreach (array('Y' => 'Year',  'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
+                $_variableName = '_' . strtolower($_elementName);
+                $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
+                    ? $params['time'][$field_array][$prefix . $_elementName]
+                    : date($_elementKey);
+            }
+            $time = mktime(0, 0, 0, $_month, $_day, $_year);
+        } else {
+            // no date found, use NOW
+            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+        }
+    } elseif ($time === null) {
+        if (array_key_exists('time', $params)) {
+            $_year = $_month = $_day = $time = null;
+        } else {
+            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+        }
+    } else {
+        list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
+    }
+
+    // make syntax "+N" or "-N" work with $start_year and $end_year
+    // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
+    foreach (array('start', 'end') as $key) {
+        $key .= '_year';
+        $t = $$key;
+        if ($t === null) {
+            $$key = (int)$_current_year;
+        } else if ($t[0] == '+') {
+            $$key = (int)($_current_year + trim(substr($t, 1)));
+        } else if ($t[0] == '-') {
+            $$key = (int)($_current_year - trim(substr($t, 1)));
+        } else {
+            $$key = (int)$$key;
+        }
+    }
+
+    // flip for ascending or descending
+    if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
+        $t = $end_year;
+        $end_year = $start_year;
+        $start_year = $t;
+    }
+
+    // generate year <select> or <input>
+    if ($display_years) {
+        $_html_years = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        } 
+        if ($year_extra) {
+            $_extra .= ' ' . $year_extra;
+        }
+        
+        if ($year_as_text) {
+            $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
+        } else {
+            $_html_years = '<select name="' . $_name . '"';
+            if ($year_id !== null || $all_id !== null) {
+                $_html_years .= ' id="' . smarty_function_escape_special_chars( 
+                    $year_id !== null ? ( $year_id ? $year_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) 
+                ) . '"';
+            }
+            if ($year_size) {
+                $_html_years .= ' size="' . $year_size . '"';
+            } 
+            $_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
+            
+            if (isset($year_empty) || isset($all_empty)) {
+                $_html_years .= '<option value="">' . ( isset($year_empty) ? $year_empty : $all_empty ) . '</option>' . $option_separator;
+            }
+            
+            $op = $start_year > $end_year ? -1 : 1;
+            for ($i=$start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
+                $_html_years .= '<option value="' . $i . '"'
+                    . ($_year == $i ? ' selected="selected"' : '')
+                    . '>' . $i . '</option>' . $option_separator;
+            }
+            
+            $_html_years .= '</select>';
+        }
+    }
+    
+    // generate month <select> or <input>
+    if ($display_months) {
+        $_html_month = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        } 
+        if ($month_extra) {
+            $_extra .= ' ' . $month_extra;
+        }
+        
+        $_html_months = '<select name="' . $_name . '"';
+        if ($month_id !== null || $all_id !== null) {
+            $_html_months .= ' id="' . smarty_function_escape_special_chars( 
+                $month_id !== null ? ( $month_id ? $month_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) 
+            ) . '"';
+        }
+        if ($month_size) {
+            $_html_months .= ' size="' . $month_size . '"';
+        } 
+        $_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
+        
+        if (isset($month_empty) || isset($all_empty)) {
+            $_html_months .= '<option value="">' . ( isset($month_empty) ? $month_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+        
+        for ($i = 1; $i <= 12; $i++) {
+            $_val = sprintf('%02d', $i);
+            $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
+            $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
+            $_html_months .= '<option value="' . $_value . '"'
+                . ($_val == $_month ? ' selected="selected"' : '')
+                . '>' . $_text . '</option>' . $option_separator;
+        }
+        
+        $_html_months .= '</select>';
+    }
+    
+    // generate day <select> or <input>
+    if ($display_days) {
+        $_html_day = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        } 
+        if ($day_extra) {
+            $_extra .= ' ' . $day_extra;
+        }
+        
+        $_html_days = '<select name="' . $_name . '"';
+        if ($day_id !== null || $all_id !== null) {
+            $_html_days .= ' id="' . smarty_function_escape_special_chars( 
+                $day_id !== null ? ( $day_id ? $day_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) 
+            ) . '"';
+        }
+        if ($day_size) {
+            $_html_days .= ' size="' . $day_size . '"';
+        } 
+        $_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
+        
+        if (isset($day_empty) || isset($all_empty)) {
+            $_html_days .= '<option value="">' . ( isset($day_empty) ? $day_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+        
+        for ($i = 1; $i <= 31; $i++) {
+            $_val = sprintf('%02d', $i);
+            $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
+            $_value = $day_value_format ==  '%02d' ? $_val : sprintf($day_value_format, $i);
+            $_html_days .= '<option value="' . $_value . '"'
+                . ($_val == $_day ? ' selected="selected"' : '')
+                . '>' . $_text . '</option>' . $option_separator;
+        }
+        
+        $_html_days .= '</select>';
+    }
+
+    // order the fields for output
+    $_html = '';
+    for ($i=0; $i <= 2; $i++) {
+        switch ($field_order[$i]) {
+            case 'Y':
+            case 'y':
+                if (isset($_html_years)) {
+                    if ($_html) {
+                        $_html .= $field_separator;
+                    }
+                    $_html .= $_html_years;
+                }
+            break;
+            
+            case 'm':
+            case 'M':
+                if (isset($_html_months)) {
+                    if ($_html) {
+                        $_html .= $field_separator;
+                    }
+                    $_html .= $_html_months;
+                }
+            break;
+            
+            case 'd':
+            case 'D':
+                if (isset($_html_days)) {
+                    if ($_html) {
+                        $_html .= $field_separator;
+                    }
+                    $_html .= $_html_days;
+                }
+            break;
+        }
+    }
+    return $_html;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_time.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_time.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_select_time.php	(revision 345)
@@ -0,0 +1,366 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_time<br>
+ * Purpose:  Prints the dropdowns for time selection
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
+ *          (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @author Monte Ohrt <monte AT ohrt DOT com>
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, $template)
+{
+    $prefix = "Time_";
+    $field_array = null;
+    $field_separator = "\n";
+    $option_separator = "\n";
+    $time = null;
+
+    $display_hours = true;
+    $display_minutes = true;
+    $display_seconds = true;
+    $display_meridian = true;
+
+    $hour_format = '%02d';
+    $hour_value_format = '%02d';
+    $minute_format = '%02d';
+    $minute_value_format = '%02d';
+    $second_format = '%02d';
+    $second_value_format = '%02d';
+
+    $hour_size = null;
+    $minute_size = null;
+    $second_size = null;
+    $meridian_size = null;
+
+    $all_empty = null;
+    $hour_empty = null;
+    $minute_empty = null;
+    $second_empty = null;
+    $meridian_empty = null;
+
+    $all_id = null;
+    $hour_id = null;
+    $minute_id = null;
+    $second_id = null;
+    $meridian_id = null;
+
+    $use_24_hours = true;
+    $minute_interval = 1;
+    $second_interval = 1;
+
+    $extra_attrs = '';
+    $all_extra = null;
+    $hour_extra = null;
+    $minute_extra = null;
+    $second_extra = null;
+    $meridian_extra = null;
+
+    foreach ($params as $_key => $_value) {
+        switch ($_key) {
+            case 'time':
+                if (!is_array($_value) && $_value !== null) {
+                    $time = smarty_make_timestamp($_value);
+                }
+                break;
+
+            case 'prefix':
+            case 'field_array':
+
+            case 'field_separator':
+            case 'option_separator':
+
+            case 'all_extra':
+            case 'hour_extra':
+            case 'minute_extra':
+            case 'second_extra':
+            case 'meridian_extra':
+
+            case 'all_empty':
+            case 'hour_empty':
+            case 'minute_empty':
+            case 'second_empty':
+            case 'meridian_empty':
+
+            case 'all_id':
+            case 'hour_id':
+            case 'minute_id':
+            case 'second_id':
+            case 'meridian_id':
+
+            case 'hour_format':
+            case 'hour_value_format':
+            case 'minute_format':
+            case 'minute_value_format':
+            case 'second_format':
+            case 'second_value_format':
+                $$_key = (string)$_value;
+                break;
+
+            case 'display_hours':
+            case 'display_minutes':
+            case 'display_seconds':
+            case 'display_meridian':
+            case 'use_24_hours':
+                $$_key = (bool)$_value;
+                break;
+
+            case 'minute_interval':
+            case 'second_interval':
+
+            case 'hour_size':
+            case 'minute_size':
+            case 'second_size':
+            case 'meridian_size':
+                $$_key = (int)$_value;
+                break;
+
+            default:
+                if (!is_array($_value)) {
+                    $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
+                } else {
+                    trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (isset($params['time']) && is_array($params['time'])) {
+        if (isset($params['time'][$prefix . 'Hour'])) {
+            // $_REQUEST[$field_array] given
+            foreach (array('H' => 'Hour',  'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
+                $_variableName = '_' . strtolower($_elementName);
+                $$_variableName = isset($params['time'][$prefix . $_elementName])
+                    ? $params['time'][$prefix . $_elementName]
+                    : date($_elementKey);
+            }
+            $_meridian = isset($params['time'][$prefix . 'Meridian'])
+                ? (' ' . $params['time'][$prefix . 'Meridian'])
+                : '';
+            $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian );
+            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+        } elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) {
+            // $_REQUEST given
+            foreach (array('H' => 'Hour',  'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
+                $_variableName = '_' . strtolower($_elementName);
+                $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
+                    ? $params['time'][$field_array][$prefix . $_elementName]
+                    : date($_elementKey);
+            }
+            $_meridian = isset($params['time'][$field_array][$prefix . 'Meridian'])
+                ? (' ' . $params['time'][$field_array][$prefix . 'Meridian'])
+                : '';
+            $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian );
+            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+        } else {
+            // no date found, use NOW
+            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+        }
+    } elseif ($time === null) {
+        if (array_key_exists('time', $params)) {
+            $_hour = $_minute = $_second = $time = null;
+        } else {
+            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
+        }
+    } else {
+        list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+    }
+
+    // generate hour <select>
+    if ($display_hours) {
+        $_html_hours = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        }
+        if ($hour_extra) {
+            $_extra .= ' ' . $hour_extra;
+        }
+
+        $_html_hours = '<select name="' . $_name . '"';
+        if ($hour_id !== null || $all_id !== null) {
+            $_html_hours .= ' id="' . smarty_function_escape_special_chars(
+                $hour_id !== null ? ( $hour_id ? $hour_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
+            ) . '"';
+        }
+        if ($hour_size) {
+            $_html_hours .= ' size="' . $hour_size . '"';
+        }
+        $_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
+
+        if (isset($hour_empty) || isset($all_empty)) {
+            $_html_hours .= '<option value="">' . ( isset($hour_empty) ? $hour_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+
+        $start = $use_24_hours ? 0 : 1;
+        $end = $use_24_hours ? 23 : 12;
+        for ($i=$start; $i <= $end; $i++) {
+            $_val = sprintf('%02d', $i);
+            $_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
+            $_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
+
+            if (!$use_24_hours) {
+                $_hour12 = $_hour == 0
+                    ? 12
+                    : ($_hour <= 12 ? $_hour : $_hour -12);
+            }
+
+            $selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
+            $_html_hours .= '<option value="' . $_value . '"'
+                . ($selected ? ' selected="selected"' : '')
+                . '>' . $_text . '</option>' . $option_separator;
+        }
+
+        $_html_hours .= '</select>';
+    }
+
+    // generate minute <select>
+    if ($display_minutes) {
+        $_html_minutes = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        }
+        if ($minute_extra) {
+            $_extra .= ' ' . $minute_extra;
+        }
+
+        $_html_minutes = '<select name="' . $_name . '"';
+        if ($minute_id !== null || $all_id !== null) {
+            $_html_minutes .= ' id="' . smarty_function_escape_special_chars(
+                $minute_id !== null ? ( $minute_id ? $minute_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
+            ) . '"';
+        }
+        if ($minute_size) {
+            $_html_minutes .= ' size="' . $minute_size . '"';
+        }
+        $_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
+
+        if (isset($minute_empty) || isset($all_empty)) {
+            $_html_minutes .= '<option value="">' . ( isset($minute_empty) ? $minute_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+
+        $selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
+        for ($i=0; $i <= 59; $i += $minute_interval) {
+            $_val = sprintf('%02d', $i);
+            $_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
+            $_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
+            $_html_minutes .= '<option value="' . $_value . '"'
+                . ($selected === $i ? ' selected="selected"' : '')
+                . '>' . $_text . '</option>' . $option_separator;
+        }
+
+        $_html_minutes .= '</select>';
+    }
+
+    // generate second <select>
+    if ($display_seconds) {
+        $_html_seconds = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        }
+        if ($second_extra) {
+            $_extra .= ' ' . $second_extra;
+        }
+
+        $_html_seconds = '<select name="' . $_name . '"';
+        if ($second_id !== null || $all_id !== null) {
+            $_html_seconds .= ' id="' . smarty_function_escape_special_chars(
+                $second_id !== null ? ( $second_id ? $second_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
+            ) . '"';
+        }
+        if ($second_size) {
+            $_html_seconds .= ' size="' . $second_size . '"';
+        }
+        $_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
+
+        if (isset($second_empty) || isset($all_empty)) {
+            $_html_seconds .= '<option value="">' . ( isset($second_empty) ? $second_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+
+        $selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
+        for ($i=0; $i <= 59; $i += $second_interval) {
+            $_val = sprintf('%02d', $i);
+            $_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
+            $_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
+            $_html_seconds .= '<option value="' . $_value . '"'
+                . ($selected === $i ? ' selected="selected"' : '')
+                . '>' . $_text . '</option>' . $option_separator;
+        }
+
+        $_html_seconds .= '</select>';
+    }
+
+    // generate meridian <select>
+    if ($display_meridian && !$use_24_hours) {
+        $_html_meridian = '';
+        $_extra = '';
+        $_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
+        if ($all_extra) {
+            $_extra .= ' ' . $all_extra;
+        }
+        if ($meridian_extra) {
+            $_extra .= ' ' . $meridian_extra;
+        }
+
+        $_html_meridian = '<select name="' . $_name . '"';
+        if ($meridian_id !== null || $all_id !== null) {
+            $_html_meridian .= ' id="' . smarty_function_escape_special_chars(
+                $meridian_id !== null ? ( $meridian_id ? $meridian_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
+            ) . '"';
+        }
+        if ($meridian_size) {
+            $_html_meridian .= ' size="' . $meridian_size . '"';
+        }
+        $_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
+
+        if (isset($meridian_empty) || isset($all_empty)) {
+            $_html_meridian .= '<option value="">' . ( isset($meridian_empty) ? $meridian_empty : $all_empty ) . '</option>' . $option_separator;
+        }
+
+        $_html_meridian .= '<option value="am"'. ($_hour < 12 ? ' selected="selected"' : '') .'>AM</option>' . $option_separator
+            . '<option value="pm"'. ($_hour < 12 ? '' : ' selected="selected"') .'>PM</option>' . $option_separator
+            . '</select>';
+    }
+
+    $_html = '';
+    foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
+        if (isset($$k)) {
+            if ($_html) {
+                $_html .= $field_separator;
+            }
+            $_html .= $$k;
+        }
+    }
+
+    return $_html;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_table.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_table.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.html_table.php	(revision 345)
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_table<br>
+ * Date:     Feb 17, 2003<br>
+ * Purpose:  make an html table from an array of data<br>
+ * Params:
+ * <pre>
+ * - loop       - array to loop through
+ * - cols       - number of columns, comma separated list of column names
+ *                or array of column names
+ * - rows       - number of rows
+ * - table_attr - table attributes
+ * - th_attr    - table heading attributes (arrays are cycled)
+ * - tr_attr    - table row attributes (arrays are cycled)
+ * - td_attr    - table cell attributes (arrays are cycled)
+ * - trailpad   - value to pad trailing cells with
+ * - caption    - text for caption element
+ * - vdir       - vertical direction (default: "down", means top-to-bottom)
+ * - hdir       - horizontal direction (default: "right", means left-to-right)
+ * - inner      - inner loop (default "cols": print $loop line by line,
+ *                $loop will be printed column by column otherwise)
+ * </pre>
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version 1.1
+ * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
+ *          (Smarty online manual)
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string
+ */
+function smarty_function_html_table($params, $template)
+{
+    $table_attr = 'border="1"';
+    $tr_attr = '';
+    $th_attr = '';
+    $td_attr = '';
+    $cols = $cols_count = 3;
+    $rows = 3;
+    $trailpad = '&nbsp;';
+    $vdir = 'down';
+    $hdir = 'right';
+    $inner = 'cols';
+    $caption = '';
+    $loop = null;
+
+    if (!isset($params['loop'])) {
+        trigger_error("html_table: missing 'loop' parameter",E_USER_WARNING);
+        return;
+    }
+
+    foreach ($params as $_key => $_value) {
+        switch ($_key) {
+            case 'loop':
+                $$_key = (array)$_value;
+                break;
+
+            case 'cols':
+                if (is_array($_value) && !empty($_value)) {
+                    $cols = $_value;
+                    $cols_count = count($_value);
+                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+                    $cols = explode(',', $_value);
+                    $cols_count = count($cols);
+                } elseif (!empty($_value)) {
+                    $cols_count = (int)$_value;
+                } else {
+                    $cols_count = $cols;
+                }
+                break;
+
+            case 'rows':
+                $$_key = (int)$_value;
+                break;
+
+            case 'table_attr':
+            case 'trailpad':
+            case 'hdir':
+            case 'vdir':
+            case 'inner':
+            case 'caption':
+                $$_key = (string)$_value;
+                break;
+
+            case 'tr_attr':
+            case 'td_attr':
+            case 'th_attr':
+                $$_key = $_value;
+                break;
+        }
+    }
+
+    $loop_count = count($loop);
+    if (empty($params['rows'])) {
+        /* no rows specified */
+        $rows = ceil($loop_count / $cols_count);
+    } elseif (empty($params['cols'])) {
+        if (!empty($params['rows'])) {
+            /* no cols specified, but rows */
+            $cols_count = ceil($loop_count / $rows);
+        }
+    }
+
+    $output = "<table $table_attr>\n";
+
+    if (!empty($caption)) {
+        $output .= '<caption>' . $caption . "</caption>\n";
+    }
+
+    if (is_array($cols)) {
+        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+        $output .= "<thead><tr>\n";
+
+        for ($r = 0; $r < $cols_count; $r++) {
+            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+            $output .= $cols[$r];
+            $output .= "</th>\n";
+        }
+        $output .= "</tr></thead>\n";
+    }
+
+    $output .= "<tbody>\n";
+    for ($r = 0; $r < $rows; $r++) {
+        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+        $rx = ($vdir == 'down') ? $r * $cols_count : ($rows-1 - $r) * $cols_count;
+
+        for ($c = 0; $c < $cols_count; $c++) {
+            $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count-1 - $c;
+            if ($inner != 'cols') {
+                /* shuffle x to loop over rows*/
+                $x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
+            }
+
+            if ($x < $loop_count) {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+            } else {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+            }
+        }
+        $output .= "</tr>\n";
+    }
+    $output .= "</tbody>\n";
+    $output .= "</table>\n";
+
+    return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no)
+{
+    if (!is_array($var)) {
+        $ret = $var;
+    } else {
+        $ret = $var[$no % count($var)];
+    }
+
+    return ($ret) ? ' ' . $ret : '';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.mailto.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.mailto.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.mailto.php	(revision 345)
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type:     function<br>
+ * Name:     mailto<br>
+ * Date:     May 21, 2002
+ * Purpose:  automate mailto address link creation, and optionally encode them.<br>
+ * Params:
+ * <pre>
+ * - address    - (required) - e-mail address
+ * - text       - (optional) - text to display, default is address
+ * - encode     - (optional) - can be one of:
+ *                             * none : no encoding (default)
+ *                             * javascript : encode with javascript
+ *                             * javascript_charcode : encode with javascript charcode
+ *                             * hex : encode with hexidecimal (no javascript)
+ * - cc         - (optional) - address(es) to carbon copy
+ * - bcc        - (optional) - address(es) to blind carbon copy
+ * - subject    - (optional) - e-mail subject
+ * - newsgroups - (optional) - newsgroup(s) to post to
+ * - followupto - (optional) - address(es) to follow up to
+ * - extra      - (optional) - extra tags for the href link
+ * </pre>
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
+ *          (Smarty online manual)
+ * @version 1.2
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string
+ */
+function smarty_function_mailto($params, $template)
+{
+    static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
+    $extra = '';
+
+    if (empty($params['address'])) {
+        trigger_error("mailto: missing 'address' parameter",E_USER_WARNING);
+        return;
+    } else {
+        $address = $params['address'];
+    }
+
+    $text = $address;
+    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+    // so, don't encode it.
+    $search = array('%40', '%2C');
+    $replace = array('@', ',');
+    $mail_parms = array();
+    foreach ($params as $var => $value) {
+        switch ($var) {
+            case 'cc':
+            case 'bcc':
+            case 'followupto':
+                if (!empty($value))
+                    $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
+                break;
+
+            case 'subject':
+            case 'newsgroups':
+                $mail_parms[] = $var . '=' . rawurlencode($value);
+                break;
+
+            case 'extra':
+            case 'text':
+                $$var = $value;
+
+            default:
+        }
+    }
+
+    if ($mail_parms) {
+        $address .= '?' . join('&', $mail_parms);
+    }
+    
+    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+    if (!isset($_allowed_encoding[$encode])) {
+        trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
+        return;
+    }
+    // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
+    if ($encode == 'javascript') {
+        $string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
+
+        $js_encode = '';
+        for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
+            $js_encode .= '%' . bin2hex($string[$x]);
+        }
+
+        return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
+    } elseif ($encode == 'javascript_charcode') {
+        $string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
+
+        for($x = 0, $y = strlen($string); $x < $y; $x++) {
+            $ord[] = ord($string[$x]);
+        }
+
+        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"
+            . "{document.write(String.fromCharCode("
+            . implode(',', $ord)
+            . "))"
+            . "}\n"
+            . "</script>\n";
+
+        return $_ret;
+    } elseif ($encode == 'hex') {
+        preg_match('!^(.*)(\?.*)$!', $address, $match);
+        if (!empty($match[2])) {
+            trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING);
+            return;
+        }
+        $address_encode = '';
+        for ($x = 0, $_length = strlen($address); $x < $_length; $x++) {
+            if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) {
+                $address_encode .= '%' . bin2hex($address[$x]);
+            } else {
+                $address_encode .= $address[$x];
+            }
+        }
+        $text_encode = '';
+        for ($x = 0, $_length = strlen($text); $x < $_length; $x++) {
+            $text_encode .= '&#x' . bin2hex($text[$x]) . ';';
+        }
+
+        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
+        return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
+    } else {
+        // no encoding
+        return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.math.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.math.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/function.math.php	(revision 345)
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * This plugin is only for Smarty2 BC
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type:     function<br>
+ * Name:     math<br>
+ * Purpose:  handle math computations in template
+ *
+ * @link http://www.smarty.net/manual/en/language.function.math.php {math}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array                    $params   parameters
+ * @param Smarty_Internal_Template $template template object
+ * @return string|null
+ */
+function smarty_function_math($params, $template)
+{
+    static $_allowed_funcs = array(
+        'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
+        'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
+        'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true
+    );
+    // be sure equation parameter is present
+    if (empty($params['equation'])) {
+        trigger_error("math: missing equation parameter",E_USER_WARNING);
+        return;
+    }
+
+    $equation = $params['equation'];
+
+    // make sure parenthesis are balanced
+    if (substr_count($equation,"(") != substr_count($equation,")")) {
+        trigger_error("math: unbalanced parenthesis",E_USER_WARNING);
+        return;
+    }
+
+    // match all vars in equation, make sure all are passed
+    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match);
+
+    foreach($match[1] as $curr_var) {
+        if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
+            trigger_error("math: function call $curr_var not allowed",E_USER_WARNING);
+            return;
+        }
+    }
+
+    foreach($params as $key => $val) {
+        if ($key != "equation" && $key != "format" && $key != "assign") {
+            // make sure value is not empty
+            if (strlen($val)==0) {
+                trigger_error("math: parameter $key is empty",E_USER_WARNING);
+                return;
+            }
+            if (!is_numeric($val)) {
+                trigger_error("math: parameter $key: is not numeric",E_USER_WARNING);
+                return;
+            }
+            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+        }
+    }
+    $smarty_math_result = null;
+    eval("\$smarty_math_result = ".$equation.";");
+
+    if (empty($params['format'])) {
+        if (empty($params['assign'])) {
+            return $smarty_math_result;
+        } else {
+            $template->assign($params['assign'],$smarty_math_result);
+        }
+    } else {
+        if (empty($params['assign'])){
+            printf($params['format'],$smarty_math_result);
+        } else {
+            $template->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+        }
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.capitalize.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.capitalize.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.capitalize.php	(revision 345)
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty capitalize modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     capitalize<br>
+ * Purpose:  capitalize words in the string
+ *
+ * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
+ *
+ * @param string  $string    string to capitalize
+ * @param boolean $uc_digits also capitalize "x123" to "X123"
+ * @param boolean $lc_rest   capitalize first letters, lowercase all following letters "aAa" to "Aaa"
+ * @return string capitalized string
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @author Rodney Rehm
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
+{
+    if (Smarty::$_MBSTRING) {
+        if ($lc_rest) {
+            // uppercase (including hyphenated words)
+            $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET );
+        } else {
+            // uppercase word breaks
+            $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $string);
+        }
+        // check uc_digits case
+        if (!$uc_digits) {
+            if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
+                foreach($matches[1] as $match) {
+                    $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0]));
+                }
+            } 
+        }
+        $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $upper_string);
+        return $upper_string;
+    }
+    
+    // lowercase first
+    if ($lc_rest) {
+        $string = strtolower($string);
+    }
+    // uppercase (including hyphenated words)
+    $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string); 
+    // check uc_digits case
+    if (!$uc_digits) {
+        if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
+            foreach($matches[1] as $match) {
+                $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0]));
+            }
+        } 
+    }
+    $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string);
+    return $upper_string;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.date_format.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.date_format.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.date_format.php	(revision 345)
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty date_format modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     date_format<br>
+ * Purpose:  format datestamps via strftime<br>
+ * Input:<br>
+ *          - string: input date string
+ *          - format: strftime format for output
+ *          - default_date: default date if $string is empty
+ * 
+ * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @param string $string       input date string
+ * @param string $format       strftime format for output
+ * @param string $default_date default date if $string is empty
+ * @param string $formatter    either 'strftime' or 'auto'
+ * @return string |void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format=null, $default_date='', $formatter='auto')
+{
+    if ($format === null) {
+        $format = Smarty::$_DATE_FORMAT;
+    }
+    /**
+    * Include the {@link shared.make_timestamp.php} plugin
+    */
+    require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+    if ($string != '') {
+        $timestamp = smarty_make_timestamp($string);
+    } elseif ($default_date != '') {
+        $timestamp = smarty_make_timestamp($default_date);
+    } else {
+        return;
+    } 
+    if($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) {
+        if (DS == '\\') {
+            $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
+            $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+            if (strpos($format, '%e') !== false) {
+                $_win_from[] = '%e';
+                $_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
+            } 
+            if (strpos($format, '%l') !== false) {
+                $_win_from[] = '%l';
+                $_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
+            } 
+            $format = str_replace($_win_from, $_win_to, $format);
+        } 
+        return strftime($format, $timestamp);
+    } else {
+        return date($format, $timestamp);
+    }
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.debug_print_var.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.debug_print_var.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.debug_print_var.php	(revision 345)
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Smarty plugin
+ * 
+ * @package Smarty
+ * @subpackage Debug
+ */
+
+/**
+ * Smarty debug_print_var modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     debug_print_var<br>
+ * Purpose:  formats variable contents for display in the console
+ *
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @param array|object $var     variable to be formatted
+ * @param integer      $depth   maximum recursion depth if $var is an array
+ * @param integer      $length  maximum string length if $var is a string
+ * @return string 
+ */
+function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40)
+{
+    $_replace = array("\n" => '<i>\n</i>',
+        "\r" => '<i>\r</i>',
+        "\t" => '<i>\t</i>'
+        );
+
+    switch (gettype($var)) {
+        case 'array' :
+            $results = '<b>Array (' . count($var) . ')</b>';
+            foreach ($var as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                 . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
+                 . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                $depth--;
+            } 
+            break;
+            
+        case 'object' :
+            $object_vars = get_object_vars($var);
+            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+            foreach ($object_vars as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                 . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
+                 . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                $depth--;
+            } 
+            break;
+            
+        case 'boolean' :
+        case 'NULL' :
+        case 'resource' :
+            if (true === $var) {
+                $results = 'true';
+            } elseif (false === $var) {
+                $results = 'false';
+            } elseif (null === $var) {
+                $results = 'null';
+            } else {
+                $results = htmlspecialchars((string) $var);
+            } 
+            $results = '<i>' . $results . '</i>';
+            break;
+            
+        case 'integer' :
+        case 'float' :
+            $results = htmlspecialchars((string) $var);
+            break;
+            
+        case 'string' :
+            $results = strtr($var, $_replace);
+            if (Smarty::$_MBSTRING) {
+                if (mb_strlen($var, Smarty::$_CHARSET) > $length) {
+                    $results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...';
+                }
+            } else {
+                if (isset($var[$length])) {
+                    $results = substr($var, 0, $length - 3) . '...';
+                }
+            }
+
+            $results = htmlspecialchars('"' . $results . '"');
+            break;
+            
+        case 'unknown type' :
+        default :
+            $results = strtr((string) $var, $_replace);
+            if (Smarty::$_MBSTRING) {
+                if (mb_strlen($results, Smarty::$_CHARSET) > $length) {
+                    $results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...';
+                }
+            } else {
+                if (strlen($results) > $length) {
+                    $results = substr($results, 0, $length - 3) . '...';
+                }
+            }
+             
+            $results = htmlspecialchars($results);
+    } 
+
+    return $results;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.escape.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.escape.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.escape.php	(revision 345)
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     escape<br>
+ * Purpose:  escape string for output
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string  $string        input string
+ * @param string  $esc_type      escape type
+ * @param string  $char_set      character set, used for htmlspecialchars() or htmlentities()
+ * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
+ * @return string escaped input string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
+{
+    if (!$char_set) {
+        $char_set = Smarty::$_CHARSET;
+    }
+
+    switch ($esc_type) {
+        case 'html':
+            return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
+
+        case 'htmlall':
+            if (Smarty::$_MBSTRING) {
+                // mb_convert_encoding ignores htmlspecialchars()
+                $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
+                // htmlentities() won't convert everything, so use mb_convert_encoding
+                return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
+            }
+
+            // no MBString fallback
+            return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
+
+        case 'url':
+            return rawurlencode($string);
+
+        case 'urlpathinfo':
+            return str_replace('%2F', '/', rawurlencode($string));
+
+        case 'quotes':
+            // escape unescaped single quotes
+            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+        case 'hex':
+            // escape every byte into hex
+            // Note that the UTF-8 encoded character Ã€ will be represented as %c3%a4
+            $return = '';
+            $_length = strlen($string);
+            for ($x = 0; $x < $_length; $x++) {
+                $return .= '%' . bin2hex($string[$x]);
+            }
+            return $return;
+
+        case 'hexentity':
+            $return = '';
+            if (Smarty::$_MBSTRING) {
+                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+                $return = '';
+                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+                    $return .= '&#x' . strtoupper(dechex($unicode)) . ';';
+                }
+                return $return;
+            }
+            // no MBString fallback
+            $_length = strlen($string);
+            for ($x = 0; $x < $_length; $x++) {
+                $return .= '&#x' . bin2hex($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'decentity':
+            $return = '';
+            if (Smarty::$_MBSTRING) {
+                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+                $return = '';
+                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+                    $return .= '&#' . $unicode . ';';
+                }
+                return $return;
+            }
+            // no MBString fallback
+            $_length = strlen($string);
+            for ($x = 0; $x < $_length; $x++) {
+                $return .= '&#' . ord($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'javascript':
+            // escape quotes and backslashes, newlines, etc.
+            return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/'));
+
+        case 'mail':
+            if (Smarty::$_MBSTRING) {
+                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
+                return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
+            }
+            // no MBString fallback
+            return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
+
+        case 'nonstd':
+            // escape non-standard chars, such as ms document quotes
+            $return = '';
+            if (Smarty::$_MBSTRING) {
+                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+                    if ($unicode >= 126) {
+                        $return .= '&#' . $unicode . ';';
+                    } else {
+                        $return .= chr($unicode);
+                    }
+                }
+                return $return;
+            }
+
+            $_length = strlen($string);
+            for ($_i = 0; $_i < $_length; $_i++) {
+                $_ord = ord(substr($string, $_i, 1));
+                // non-standard char, escape it
+                if ($_ord >= 126) {
+                    $return .= '&#' . $_ord . ';';
+                } else {
+                    $return .= substr($string, $_i, 1);
+                }
+            }
+            return $return;
+
+        default:
+            return $string;
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.regex_replace.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.regex_replace.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.regex_replace.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     regex_replace<br>
+ * Purpose:  regular expression search/replace
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ *          regex_replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string       $string   input string
+ * @param string|array $search   regular expression(s) to search for
+ * @param string|array $replace  string(s) that should be replaced
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+    if(is_array($search)) {
+        foreach($search as $idx => $s) {
+            $search[$idx] = _smarty_regex_replace_check($s);
+        }
+    } else {
+        $search = _smarty_regex_replace_check($search);
+    }
+    return preg_replace($search, $replace, $string);
+}
+
+/**
+ * @param  string $search string(s) that should be replaced
+ * @return string
+ * @ignore
+ */
+function _smarty_regex_replace_check($search)
+{
+    // null-byte injection detection
+    // anything behind the first null-byte is ignored
+    if (($pos = strpos($search,"\0")) !== false) {
+        $search = substr($search,0,$pos);
+    }
+    // remove eval-modifier from $search
+    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+    }
+    return $search;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.replace.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.replace.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.replace.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty replace modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     replace<br>
+ * Purpose:  simple search/replace
+ * 
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @author Uwe Tews 
+ * @param string $string  input string
+ * @param string $search  text to search for
+ * @param string $replace replacement text
+ * @return string 
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+    if (Smarty::$_MBSTRING) {
+        require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
+        return smarty_mb_str_replace($search, $replace, $string);
+    }
+    
+    return str_replace($search, $replace, $string);
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.spacify.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.spacify.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.spacify.php	(revision 345)
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty spacify modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     spacify<br>
+ * Purpose:  add spaces between characters in a string
+ * 
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @param string $string       input string
+ * @param string $spacify_char string to insert between characters.
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+    // wellâŠ what about charsets besides latin and UTF-8?
+    return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY));
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.truncate.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.truncate.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifier.truncate.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+ 
+/**
+ * Smarty truncate modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     truncate<br>
+ * Purpose:  Truncate a string to a certain length if necessary,
+ *               optionally splitting in the middle of a word, and
+ *               appending the $etc string or inserting $etc into the middle.
+ * 
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> 
+ * @param string  $string      input string
+ * @param integer $length      length of truncated text
+ * @param string  $etc         end string
+ * @param boolean $break_words truncate at word boundary
+ * @param boolean $middle      truncate in the middle of text
+ * @return string truncated string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
+    if ($length == 0)
+        return '';
+
+    if (Smarty::$_MBSTRING) {
+        if (mb_strlen($string, Smarty::$_CHARSET) > $length) {
+            $length -= min($length, mb_strlen($etc, Smarty::$_CHARSET));
+            if (!$break_words && !$middle) {
+                $string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '', mb_substr($string, 0, $length + 1, Smarty::$_CHARSET));
+            } 
+            if (!$middle) {
+                return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
+            }
+            return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET);
+        }
+        return $string;
+    }
+    
+    // no MBString fallback
+    if (isset($string[$length])) {
+        $length -= min($length, strlen($etc));
+        if (!$break_words && !$middle) {
+            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
+        } 
+        if (!$middle) {
+            return substr($string, 0, $length) . $etc;
+        }
+        return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2);
+    }
+    return $string;
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.cat.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.cat.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.cat.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     cat<br>
+ * Date:     Feb 24, 2003<br>
+ * Purpose:  catenate a value to a variable<br>
+ * Input:    string to catenate<br>
+ * Example:  {$var|cat:"foo"}
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ *          (Smarty online manual)
+ * @author   Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_cat($params, $compiler)
+{
+    return '('.implode(').(', $params).')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_characters.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_characters.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_characters.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_characteres<br>
+ * Purpose:  count the number of characters in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_characters($params, $compiler)
+{
+    if (!isset($params[1]) || $params[1] != 'true') {
+        return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)';
+    }
+    if (Smarty::$_MBSTRING) {
+        return 'mb_strlen(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+    }
+    // no MBString fallback
+    return 'strlen(' . $params[0] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_paragraphs.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_paragraphs.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_paragraphs.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_paragraphs<br>
+ * Purpose:  count the number of paragraphs in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_paragraphs (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_paragraphs($params, $compiler)
+{
+    // count \r or \n characters
+    return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_sentences.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_sentences.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_sentences.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_sentences
+ * Purpose:  count the number of sentences in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_sentences (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_sentences($params, $compiler)
+{
+    // find periods, question marks, exclamation marks with a word before but not after.
+    return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_words.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_words.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.count_words.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_words<br>
+ * Purpose:  count the number of words in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+*/
+function smarty_modifiercompiler_count_words($params, $compiler)
+{
+    if (Smarty::$_MBSTRING) {
+        // return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+        // expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592
+        return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+    }
+    // no MBString fallback
+    return 'str_word_count(' . $params[0] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.default.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.default.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.default.php	(revision 345)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     default<br>
+ * Purpose:  designate default value for empty variables
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_default ($params, $compiler)
+{
+    $output = $params[0];
+    if (!isset($params[1])) {
+        $params[1] = "''";
+    }
+    
+    array_shift($params);
+    foreach ($params as $param) {
+        $output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
+    }
+    return $output;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.escape.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.escape.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.escape.php	(revision 345)
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * @ignore
+ */
+require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     escape<br>
+ * Purpose:  escape string for output
+ *
+ * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_escape($params, $compiler)
+{
+    try {
+        $esc_type = smarty_literal_compiler_param($params, 1, 'html');
+        $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
+        $double_encode = smarty_literal_compiler_param($params, 3, true);
+
+        if (!$char_set) {
+            $char_set = Smarty::$_CHARSET;
+        }
+
+        switch ($esc_type) {
+            case 'html':
+                return 'htmlspecialchars('
+                    . $params[0] .', ENT_QUOTES, '
+                    . var_export($char_set, true) . ', '
+                    . var_export($double_encode, true) . ')';
+
+            case 'htmlall':
+                if (Smarty::$_MBSTRING) {
+                    return 'mb_convert_encoding(htmlspecialchars('
+                        . $params[0] .', ENT_QUOTES, '
+                        . var_export($char_set, true) . ', '
+                        . var_export($double_encode, true)
+                        . '), "HTML-ENTITIES", '
+                        . var_export($char_set, true) . ')';
+                }
+
+                // no MBString fallback
+                return 'htmlentities('
+                    . $params[0] .', ENT_QUOTES, '
+                    . var_export($char_set, true) . ', '
+                    . var_export($double_encode, true) . ')';
+
+            case 'url':
+                return 'rawurlencode(' . $params[0] . ')';
+
+            case 'urlpathinfo':
+                return 'str_replace("%2F", "/", rawurlencode(' . $params[0] . '))';
+
+            case 'quotes':
+                // escape unescaped single quotes
+                return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[0] . ')';
+
+            case 'javascript':
+                // escape quotes and backslashes, newlines, etc.
+                return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
+
+        }
+    } catch(SmartyException $e) {
+        // pass through to regular plugin fallback
+    }
+
+    // could not optimize |escape call, so fallback to regular plugin
+    if ($compiler->tag_nocache | $compiler->nocache) {
+        $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
+        $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+    } else {
+        $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
+        $compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+    }
+    return 'smarty_modifier_escape(' . join( ', ', $params ) . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.from_charset.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.from_charset.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.from_charset.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty from_charset modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     from_charset<br>
+ * Purpose:  convert character encoding from $charset to internal encoding
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_from_charset($params, $compiler)
+{
+    if (!Smarty::$_MBSTRING) {
+        // FIXME: (rodneyrehm) shouldn't this throw an error?
+        return $params[0];
+    }
+
+    if (!isset($params[1])) {
+        $params[1] = '"ISO-8859-1"';
+    }
+
+    return 'mb_convert_encoding(' . $params[0] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[1] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.indent.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.indent.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.indent.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     indent<br>
+ * Purpose:  indent lines of text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_indent($params, $compiler)
+{
+    if (!isset($params[1])) {
+        $params[1] = 4;
+    }
+    if (!isset($params[2])) {
+        $params[2] = "' '";
+    }
+    return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.lower.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.lower.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.lower.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     lower<br>
+ * Purpose:  convert string to lowercase
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_lower($params, $compiler)
+{
+    if (Smarty::$_MBSTRING) {
+        return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ;
+    }
+    // no MBString fallback
+    return 'strtolower(' . $params[0] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.noprint.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.noprint.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.noprint.php	(revision 345)
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty noprint modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     noprint<br>
+ * Purpose:  return an empty string
+ *
+ * @author   Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_noprint($params, $compiler)
+{
+    return "''";
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.string_format.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.string_format.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.string_format.php	(revision 345)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     string_format<br>
+ * Purpose:  format strings via sprintf
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_string_format($params, $compiler)
+{
+    return 'sprintf(' . $params[1] . ',' . $params[0] . ')';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip<br>
+ * Purpose:  Replace all repeated spaces, newlines, tabs
+ *              with a single space or supplied replacement string.<br>
+ * Example:  {$var|strip} {$var|strip:"&nbsp;"}<br>
+ * Date:     September 25th, 2002
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_strip($params, $compiler)
+{
+    if (!isset($params[1])) {
+        $params[1] = "' '";
+    }
+    return "preg_replace('!\s+!" . Smarty::$_UTF8_MODIFIER . "', {$params[1]},{$params[0]})";
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip_tags.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip_tags.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.strip_tags.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip_tags<br>
+ * Purpose:  strip html tags from text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_strip_tags($params, $compiler)
+{
+   if (!isset($params[1])) {
+        $params[1] = true;
+    }
+    if ($params[1] === true) {
+        return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
+    } else {
+        return 'strip_tags(' . $params[0] . ')';
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.to_charset.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.to_charset.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.to_charset.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty to_charset modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     to_charset<br>
+ * Purpose:  convert character encoding from internal encoding to $charset
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_to_charset($params, $compiler)
+{
+    if (!Smarty::$_MBSTRING) {
+        // FIXME: (rodneyrehm) shouldn't this throw an error?
+        return $params[0];
+    }
+
+    if (!isset($params[1])) {
+        $params[1] = '"ISO-8859-1"';
+    }
+
+    return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', "' . addslashes(Smarty::$_CHARSET) . '")';
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.unescape.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.unescape.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.unescape.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty unescape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     unescape<br>
+ * Purpose:  unescape html entities
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_unescape($params, $compiler)
+{
+    if (!isset($params[1])) {
+        $params[1] = 'html';
+    }
+    if (!isset($params[2])) {
+        $params[2] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
+    } else {
+        $params[2] = "'" . $params[2] . "'";
+    }
+
+    switch (trim($params[1], '"\'')) {
+        case 'entity':
+            return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
+        case 'htmlall':
+            if (Smarty::$_MBSTRING) {
+                return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
+            }
+            return 'html_entity_decode(' . $params[0] . ', ENT_QUOTES, ' . $params[2] . ')';
+
+        case 'html':
+            return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
+
+        default:
+            return $params[0];
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.upper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.upper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.upper.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty upper modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     lower<br>
+ * Purpose:  convert string to uppercase
+ * 
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
+ * @author Uwe Tews 
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_upper($params, $compiler)
+{
+    if (Smarty::$_MBSTRING) {
+        return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ;
+    }
+    // no MBString fallback
+    return 'strtoupper(' . $params[0] . ')';
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.wordwrap.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.wordwrap.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/modifiercompiler.wordwrap.php	(revision 345)
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty wordwrap modifier plugin
+ * 
+ * Type:     modifier<br>
+ * Name:     wordwrap<br>
+ * Purpose:  wrap a string of text at a given length
+ * 
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
+ * @author Uwe Tews 
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_wordwrap($params, $compiler)
+{
+    if (!isset($params[1])) {
+        $params[1] = 80;
+    } 
+    if (!isset($params[2])) {
+        $params[2] = '"\n"';
+    } 
+    if (!isset($params[3])) {
+        $params[3] = 'false';
+    } 
+    $function = 'wordwrap';
+    if (Smarty::$_MBSTRING) {
+        if ($compiler->tag_nocache | $compiler->nocache) {
+            $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
+            $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+        } else {
+            $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
+            $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+        }
+        $function = 'smarty_mb_wordwrap';
+    }
+    return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')';
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/outputfilter.trimwhitespace.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/outputfilter.trimwhitespace.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/outputfilter.trimwhitespace.php	(revision 345)
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFilter
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * Trim unnecessary whitespace from HTML markup.
+ *
+ * @author   Rodney Rehm
+ * @param string                   $source input string
+ * @param Smarty_Internal_Template $smarty Smarty object
+ * @return string filtered output
+ */
+function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
+{
+    $store = array();
+    $_store = 0;
+    $_offset = 0;
+
+    // Unify Line-Breaks to \n
+    $source = preg_replace("/\015\012|\015|\012/", "\n", $source);
+
+    // capture Internet Explorer Conditional Comments
+    if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+        foreach ($matches as $match) {
+            $store[] = $match[0][0];
+            $_length = strlen($match[0][0]);
+            $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
+            $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
+
+            $_offset += $_length - strlen($replace);
+            $_store++;
+        }
+    }
+
+    // Strip all HTML-Comments
+    $source = preg_replace( '#<!--.*?-->#ms', '', $source );
+
+    // capture html elements not to be messed with
+    $_offset = 0;
+    if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+        foreach ($matches as $match) {
+            $store[] = $match[0][0];
+            $_length = strlen($match[0][0]);
+            $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
+            $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
+
+            $_offset += $_length - strlen($replace);
+            $_store++;
+        }
+    }
+
+    $expressions = array(
+        // replace multiple spaces between tags by a single space
+        // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
+        '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
+        // remove spaces between attributes (but not in attribute values!)
+        '#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4',
+        // note: for some very weird reason trim() seems to remove spaces inside attributes.
+        // maybe a \0 byte or something is interfering?
+        '#^\s+<#Ss' => '<',
+        '#>\s+$#Ss' => '>',
+    );
+
+    $source = preg_replace( array_keys($expressions), array_values($expressions), $source );
+    // note: for some very weird reason trim() seems to remove spaces inside attributes.
+    // maybe a \0 byte or something is interfering?
+    // $source = trim( $source );
+
+    // capture html elements not to be messed with
+    $_offset = 0;
+    if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+        foreach ($matches as $match) {
+            $store[] = $match[0][0];
+            $_length = strlen($match[0][0]);
+            $replace = array_shift($store);
+            $source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
+
+            $_offset += strlen($replace) - $_length;
+            $_store++;
+        }
+    }
+
+    return $source;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.escape_special_chars.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.escape_special_chars.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.escape_special_chars.php	(revision 345)
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
+    /**
+     * escape_special_chars common function
+     *
+     * Function: smarty_function_escape_special_chars<br>
+     * Purpose:  used by other smarty functions to escape
+     *           special chars except for already escaped ones
+     *
+     * @author   Monte Ohrt <monte at ohrt dot com>
+     * @param string $string text that should by escaped
+     * @return string
+     */
+    function smarty_function_escape_special_chars($string)
+    {
+        if (!is_array($string)) {
+            $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
+        }
+        return $string;
+    }  
+} else {         
+    /**
+     * escape_special_chars common function
+     *
+     * Function: smarty_function_escape_special_chars<br>
+     * Purpose:  used by other smarty functions to escape
+     *           special chars except for already escaped ones
+     *
+     * @author   Monte Ohrt <monte at ohrt dot com>
+     * @param string $string text that should by escaped
+     * @return string
+     */
+    function smarty_function_escape_special_chars($string)
+    {
+        if (!is_array($string)) {
+            $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+            $string = htmlspecialchars($string);
+            $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); 
+        }
+        return $string;
+    }                                                                                                             
+} 
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.literal_compiler_param.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.literal_compiler_param.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.literal_compiler_param.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * evaluate compiler parameter
+ *
+ * @param array   $params  parameter array as given to the compiler function
+ * @param integer $index   array index of the parameter to convert
+ * @param mixed   $default value to be returned if the parameter is not present
+ * @return mixed evaluated value of parameter or $default
+ * @throws SmartyException if parameter is not a literal (but an expression, variable, âŠ)
+ * @author Rodney Rehm
+ */
+function smarty_literal_compiler_param($params, $index, $default=null)
+{
+    // not set, go default
+    if (!isset($params[$index])) {
+        return $default;
+    }
+    // test if param is a literal
+    if (!preg_match('/^([\'"]?)[a-zA-Z0-9]+(\\1)$/', $params[$index])) {
+        throw new SmartyException('$param[' . $index . '] is not a literal and is thus not evaluatable at compile time');
+    }
+
+    $t = null;
+    eval("\$t = " . $params[$index] . ";");
+    return $t;
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.make_timestamp.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.make_timestamp.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.make_timestamp.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose:  used by other smarty functions to make a timestamp from a string.
+ *
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param DateTime|int|string $string  date object, timestamp or string that can be converted using strtotime()
+ * @return int
+ */
+function smarty_make_timestamp($string)
+{
+    if (empty($string)) {
+        // use "now":
+        return time();
+    } elseif ($string instanceof DateTime) {
+        return $string->getTimestamp();
+    } elseif (strlen($string) == 14 && ctype_digit($string)) {
+        // it is mysql timestamp format of YYYYMMDDHHMMSS?
+        return mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
+                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
+    } elseif (is_numeric($string)) {
+        // it is a numeric string, we handle it as timestamp
+        return (int) $string;
+    } else {
+        // strtotime should handle it
+        $time = strtotime($string);
+        if ($time == -1 || $time === false) {
+            // strtotime() was not able to parse $string, use "now":
+            return time();
+        }
+        return $time;
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_str_replace.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_str_replace.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_str_replace.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+if (!function_exists('smarty_mb_str_replace')) {
+
+    /**
+     * Multibyte string replace
+     *
+     * @param string $search  the string to be searched
+     * @param string $replace the replacement string
+     * @param string $subject the source string
+     * @param int    &$count  number of matches found
+     * @return string replaced string
+     * @author Rodney Rehm
+     */
+    function smarty_mb_str_replace($search, $replace, $subject, &$count=0)
+    {
+        if (!is_array($search) && is_array($replace)) {
+            return false;
+        }
+        if (is_array($subject)) {
+            // call mb_replace for each single string in $subject
+            foreach ($subject as &$string) {
+                $string = &smarty_mb_str_replace($search, $replace, $string, $c);
+                $count += $c;
+            }
+        } elseif (is_array($search)) {
+            if (!is_array($replace)) {
+                foreach ($search as &$string) {
+                    $subject = smarty_mb_str_replace($string, $replace, $subject, $c);
+                    $count += $c;
+                }
+            } else {
+                $n = max(count($search), count($replace));
+                while ($n--) {
+                    $subject = smarty_mb_str_replace(current($search), current($replace), $subject, $c);
+                    $count += $c;
+                    next($search);
+                    next($replace);
+                }
+            }
+        } else {
+            $parts = mb_split(preg_quote($search), $subject);
+            $count = count($parts) - 1;
+            $subject = implode($replace, $parts);
+        }
+        return $subject;
+    }
+
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_unicode.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_unicode.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_unicode.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * convert characters to their decimal unicode equivalents
+ *
+ * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
+ * @param string $string   characters to calculate unicode of
+ * @param string $encoding encoding of $string, if null mb_internal_encoding() is used
+ * @return array sequence of unicodes
+ * @author Rodney Rehm
+ */
+function smarty_mb_to_unicode($string, $encoding=null) {
+    if ($encoding) {
+        $expanded = mb_convert_encoding($string, "UTF-32BE", $encoding);
+    } else {
+        $expanded = mb_convert_encoding($string, "UTF-32BE");
+    }
+    return unpack("N*", $expanded);
+}
+
+/**
+ * convert unicodes to the character of given encoding
+ *
+ * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
+ * @param integer|array $unicode  single unicode or list of unicodes to convert
+ * @param string        $encoding encoding of returned string, if null mb_internal_encoding() is used
+ * @return string unicode as character sequence in given $encoding
+ * @author Rodney Rehm
+ */
+function smarty_mb_from_unicode($unicode, $encoding=null) {
+    $t = '';
+    if (!$encoding) {
+        $encoding = mb_internal_encoding();
+    }
+    foreach((array) $unicode as $utf32be) {
+        $character = pack("N*", $utf32be);
+        $t .= mb_convert_encoding($character, $encoding, "UTF-32BE");
+    }
+    return $t;
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_wordwrap.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_wordwrap.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/shared.mb_wordwrap.php	(revision 345)
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+if(!function_exists('smarty_mb_wordwrap')) {
+
+    /**
+     * Wrap a string to a given number of characters
+     *
+     * @link http://php.net/manual/en/function.wordwrap.php for similarity
+     * @param string  $str   the string to wrap
+     * @param int     $width the width of the output
+     * @param string  $break the character used to break the line
+     * @param boolean $cut   ignored parameter, just for the sake of
+     * @return string wrapped string
+     * @author Rodney Rehm
+     */
+    function smarty_mb_wordwrap($str, $width=75, $break="\n", $cut=false)
+    {
+        // break words into tokens using white space as a delimiter
+        $tokens = preg_split('!(\s)!S' . Smarty::$_UTF8_MODIFIER, $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
+        $length = 0;
+        $t = '';
+        $_previous = false;
+
+        foreach ($tokens as $_token) {
+            $token_length = mb_strlen($_token, Smarty::$_CHARSET);
+            $_tokens = array($_token);
+            if ($token_length > $width) {
+                // remove last space
+                $t = mb_substr($t, 0, -1, Smarty::$_CHARSET);
+                $_previous = false;
+                $length = 0;
+
+                if ($cut) {
+                    $_tokens = preg_split('!(.{' . $width . '})!S' . Smarty::$_UTF8_MODIFIER, $_token, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
+                    // broken words go on a new line
+                    $t .= $break;
+                }
+            }
+
+            foreach ($_tokens as $token) {
+                $_space = !!preg_match('!^\s$!S' . Smarty::$_UTF8_MODIFIER, $token);
+                $token_length = mb_strlen($token, Smarty::$_CHARSET);
+                $length += $token_length;
+
+                if ($length > $width) {
+                    // remove space before inserted break
+                    if ($_previous && $token_length < $width) {
+                        $t = mb_substr($t, 0, -1, Smarty::$_CHARSET);
+                    }
+
+                    // add the break before the token
+                    $t .= $break;
+                    $length = $token_length;
+
+                    // skip space after inserting a break
+                    if ($_space) {
+                        $length = 0;
+                        continue;
+                    }
+                } else if ($token == "\n") {
+                    // hard break must reset counters
+                    $_previous = 0;
+                    $length = 0;
+                } else {
+                    // remember if we had a space or not
+                    $_previous = $_space;
+                }
+                // add the token
+                $t .= $token;
+            }
+        }
+
+        return $t;
+    }
+
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/variablefilter.htmlspecialchars.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/variablefilter.htmlspecialchars.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/plugins/variablefilter.htmlspecialchars.php	(revision 345)
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFilter
+ */
+
+/**
+ * Smarty htmlspecialchars variablefilter plugin
+ *
+ * @param string                   $source input string
+ * @param Smarty_Internal_Template $smarty Smarty object
+ * @return string filtered output
+ */
+function smarty_variablefilter_htmlspecialchars($source, $smarty)
+{
+    return htmlspecialchars($source, ENT_QUOTES, Smarty::$_CHARSET);
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource.php	(revision 345)
@@ -0,0 +1,381 @@
+<?php
+/**
+* Smarty Internal Plugin
+*
+* @package Smarty
+* @subpackage Cacher
+*/
+
+/**
+* Cache Handler API
+*
+* @package Smarty
+* @subpackage Cacher
+* @author Rodney Rehm
+*/
+abstract class Smarty_CacheResource {
+    /**
+    * cache for Smarty_CacheResource instances
+    * @var array
+    */
+    public static $resources = array();
+
+    /**
+    * resource types provided by the core
+    * @var array
+    */
+    protected static $sysplugins = array(
+        'file' => true,
+    );
+
+    /**
+    * populate Cached Object with meta data from Resource
+    *
+    * @param Smarty_Template_Cached $cached cached object
+    * @param Smarty_Internal_Template $_template template object
+    * @return void
+    */
+    public abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
+
+    /**
+    * populate Cached Object with timestamp and exists from Resource
+    *
+    * @param Smarty_Template_Cached $source cached object
+    * @return void
+    */
+    public abstract function populateTimestamp(Smarty_Template_Cached $cached);
+
+    /**
+    * Read the cached template and process header
+    *
+    * @param Smarty_Internal_Template $_template template object
+    * @param Smarty_Template_Cached $cached cached object
+    * @return booelan true or false if the cached content does not exist
+    */
+    public abstract function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null);
+
+    /**
+    * Write the rendered template output to cache
+    *
+    * @param Smarty_Internal_Template $_template template object
+    * @param string $content content to cache
+    * @return boolean success
+    */
+    public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content);
+
+    /**
+    * Return cached content
+    *
+    * @param Smarty_Internal_Template $_template template object
+    * @param string $content content of cache
+    */
+    public function getCachedContent(Smarty_Internal_Template $_template)
+    {
+        if ($_template->cached->handler->process($_template)) {
+            ob_start();
+            $_template->properties['unifunc']($_template);
+            return ob_get_clean();
+        }
+        return null;
+    }
+
+    /**
+    * Empty cache
+    *
+    * @param Smarty $smarty Smarty object
+    * @param integer $exp_time expiration time (number of seconds, not timestamp)
+    * @return integer number of cache files deleted
+    */
+    public abstract function clearAll(Smarty $smarty, $exp_time=null);
+
+    /**
+    * Empty cache for a specific template
+    *
+    * @param Smarty $smarty Smarty object
+    * @param string $resource_name template name
+    * @param string $cache_id cache id
+    * @param string $compile_id compile id
+    * @param integer $exp_time expiration time (number of seconds, not timestamp)
+    * @return integer number of cache files deleted
+    */
+    public abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
+
+
+    public function locked(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        // theoretically locking_timeout should be checked against time_limit (max_execution_time)
+        $start = microtime(true);
+        $hadLock = null;
+        while ($this->hasLock($smarty, $cached)) {
+            $hadLock = true;
+            if (microtime(true) - $start > $smarty->locking_timeout) {
+                // abort waiting for lock release
+                return false;
+            }
+            sleep(1);
+        }
+        return $hadLock;
+    }
+
+    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        // check if lock exists
+        return false;
+    }
+
+    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        // create lock
+        return true;
+    }
+
+    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        // release lock
+        return true;
+    }
+
+
+    /**
+    * Load Cache Resource Handler
+    *
+    * @param Smarty $smarty Smarty object
+    * @param string $type name of the cache resource
+    * @return Smarty_CacheResource Cache Resource Handler
+    */
+    public static function load(Smarty $smarty, $type = null)
+    {
+        if (!isset($type)) {
+            $type = $smarty->caching_type;
+        }
+
+        // try smarty's cache
+        if (isset($smarty->_cacheresource_handlers[$type])) {
+            return $smarty->_cacheresource_handlers[$type];
+        }
+        
+        // try registered resource
+        if (isset($smarty->registered_cache_resources[$type])) {
+            // do not cache these instances as they may vary from instance to instance
+            return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type];
+        }
+        // try sysplugins dir
+        if (isset(self::$sysplugins[$type])) {
+            if (!isset(self::$resources[$type])) {
+                $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
+                self::$resources[$type] = new $cache_resource_class();
+            }
+            return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
+        }
+        // try plugins dir
+        $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
+        if ($smarty->loadPlugin($cache_resource_class)) {
+            if (!isset(self::$resources[$type])) {
+                self::$resources[$type] = new $cache_resource_class();
+            }
+            return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
+        }
+        // give up
+        throw new SmartyException("Unable to load cache resource '{$type}'");
+    }
+
+    /**
+    * Invalid Loaded Cache Files
+    *
+    * @param Smarty $smarty Smarty object
+    */
+    public static function invalidLoadedCache(Smarty $smarty)
+    {
+        foreach ($smarty->template_objects as $tpl) {
+            if (isset($tpl->cached)) {
+                $tpl->cached->valid = false;
+                $tpl->cached->processed = false;
+            }
+        }
+    }
+}
+
+/**
+* Smarty Resource Data Object
+*
+* Cache Data Container for Template Files
+*
+* @package Smarty
+* @subpackage TemplateResources
+* @author Rodney Rehm
+*/
+class Smarty_Template_Cached {
+    /**
+    * Source Filepath
+    * @var string
+    */
+    public $filepath = false;
+
+    /**
+    * Source Content
+    * @var string
+    */
+    public $content = null;
+
+    /**
+    * Source Timestamp
+    * @var integer
+    */
+    public $timestamp = false;
+
+    /**
+    * Source Existance
+    * @var boolean
+    */
+    public $exists = false;
+
+    /**
+    * Cache Is Valid
+    * @var boolean
+    */
+    public $valid = false;
+
+    /**
+    * Cache was processed
+    * @var boolean
+    */
+    public $processed = false;
+
+    /**
+    * CacheResource Handler
+    * @var Smarty_CacheResource
+    */
+    public $handler = null;
+
+    /**
+    * Template Compile Id (Smarty_Internal_Template::$compile_id)
+    * @var string
+    */
+    public $compile_id = null;
+
+    /**
+    * Template Cache Id (Smarty_Internal_Template::$cache_id)
+    * @var string
+    */
+    public $cache_id = null;
+
+    /**
+    * Id for cache locking
+    * @var string
+    */
+    public $lock_id = null;
+
+    /**
+    * flag that cache is locked by this instance
+    * @var bool
+    */
+    public $is_locked = false;
+
+    /**
+    * Source Object
+    * @var Smarty_Template_Source
+    */
+    public $source = null;
+
+    /**
+    * create Cached Object container
+    *
+    * @param Smarty_Internal_Template $_template template object
+    */
+    public function __construct(Smarty_Internal_Template $_template)
+    {
+        $this->compile_id = $_template->compile_id;
+        $this->cache_id = $_template->cache_id;
+        $this->source = $_template->source;
+        $_template->cached = $this;
+        $smarty = $_template->smarty;
+
+        //
+        // load resource handler
+        //
+        $this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references
+
+        //
+        //    check if cache is valid
+        //
+        if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) {
+            $handler->populate($this, $_template);
+            return;
+        }
+        while (true) {
+            while (true) {
+                $handler->populate($this, $_template);
+                if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) {
+                    $this->valid = false;
+                } else {
+                    $this->valid = true;
+                }
+                if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) {
+                    // lifetime expired
+                    $this->valid = false;
+                }
+                if ($this->valid || !$_template->smarty->cache_locking) {
+                    break;
+                }
+                if (!$this->handler->locked($_template->smarty, $this)) {
+                    $this->handler->acquireLock($_template->smarty, $this);
+                    break 2;
+                }
+            }
+            if ($this->valid) {
+                if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) {
+                    // load cache file for the following checks
+                    if ($smarty->debugging) {
+                        Smarty_Internal_Debug::start_cache($_template);
+                    }
+                    if($handler->process($_template, $this) === false) {
+                        $this->valid = false;
+                    } else {
+                        $this->processed = true;
+                    }
+                    if ($smarty->debugging) {
+                        Smarty_Internal_Debug::end_cache($_template);
+                    }
+                } else {
+                    continue;
+                }
+            } else {
+                return;
+            }
+            if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) {
+                $this->valid = false;
+            }
+            if (!$this->valid && $_template->smarty->cache_locking) {
+                $this->handler->acquireLock($_template->smarty, $this);
+                return;
+            } else {
+                return;
+            }
+        }
+    }
+
+    /**
+    * Write this cache object to handler
+    *
+    * @param Smarty_Internal_Template $_template template object
+    * @param string $content content to cache
+    * @return boolean success
+    */
+    public function write(Smarty_Internal_Template $_template, $content)
+    {
+        if (!$_template->source->recompiled) {
+            if ($this->handler->writeCachedContent($_template, $content)) {
+                $this->timestamp = time();
+                $this->exists = true;
+                $this->valid = true;
+                if ($_template->smarty->cache_locking) {
+                    $this->handler->releaseLock($_template->smarty, $this);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_custom.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_custom.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_custom.php	(revision 345)
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+
+/**
+ * Cache Handler API
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Rodney Rehm
+ */
+abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
+
+    /**
+     * fetch cached content and its modification time from data source
+     *
+     * @param string $id         unique cache content identifier
+     * @param string $name       template name
+     * @param string $cache_id   cache id
+     * @param string $compile_id compile id
+     * @param string $content    cached content
+     * @param integer $mtime cache modification timestamp (epoch)
+     * @return void
+     */
+    protected abstract function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime);
+
+    /**
+     * Fetch cached content's modification timestamp from data source
+     *
+     * {@internal implementing this method is optional.
+     *  Only implement it if modification times can be accessed faster than loading the complete cached content.}}
+     *
+     * @param string $id         unique cache content identifier
+     * @param string $name       template name
+     * @param string $cache_id   cache id
+     * @param string $compile_id compile id
+     * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+     */
+    protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
+    {
+        return null;
+    }
+
+    /**
+     * Save content to cache
+     *
+     * @param string       $id         unique cache content identifier
+     * @param string       $name       template name
+     * @param string       $cache_id   cache id
+     * @param string       $compile_id compile id
+     * @param integer|null $exp_time   seconds till expiration or null
+     * @param string $content content to cache
+     * @return boolean success
+     */
+    protected abstract function save($id, $name, $cache_id, $compile_id, $exp_time, $content);
+
+    /**
+     * Delete content from cache
+     *
+     * @param string       $name       template name
+     * @param string       $cache_id   cache id
+     * @param string       $compile_id compile id
+     * @param integer|null $exp_time   seconds till expiration time in seconds or null
+     * @return integer number of deleted caches
+     */
+    protected abstract function delete($name, $cache_id, $compile_id, $exp_time);
+
+    /**
+     * populate Cached Object with meta data from Resource
+     *
+     * @param Smarty_Template_Cached   $cached    cached object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
+    {
+        $_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null;
+        $_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null;
+
+        $cached->filepath = sha1($cached->source->filepath . $_cache_id . $_compile_id);
+        $this->populateTimestamp($cached);
+    }
+
+    /**
+     * populate Cached Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Cached $source cached object
+     * @return void
+     */
+    public function populateTimestamp(Smarty_Template_Cached $cached)
+    {
+        $mtime = $this->fetchTimestamp($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id);
+        if ($mtime !== null) {
+            $cached->timestamp = $mtime;
+            $cached->exists = !!$cached->timestamp;
+            return;
+        }
+        $timestamp = null;
+        $this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $cached->content, $timestamp);
+        $cached->timestamp = isset($timestamp) ? $timestamp : false;
+        $cached->exists = !!$cached->timestamp;
+    }
+
+    /**
+     * Read the cached template and process the header
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if the cached content does not exist
+     */
+    public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
+    {
+        if (!$cached) {
+            $cached = $_template->cached;
+        }
+        $content = $cached->content ? $cached->content : null;
+        $timestamp = $cached->timestamp ? $cached->timestamp : null;
+        if ($content === null || !$timestamp) {
+            $this->fetch(
+                $_template->cached->filepath,
+                $_template->source->name,
+                $_template->cache_id,
+                $_template->compile_id,
+                $content,
+                $timestamp
+            );
+        }
+        if (isset($content)) {
+            $_smarty_tpl = $_template;
+            eval("?>" . $content);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Write the rendered template output to cache
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param string                   $content   content to cache
+     * @return boolean success
+     */
+    public function writeCachedContent(Smarty_Internal_Template $_template, $content)
+    {
+        return $this->save(
+            $_template->cached->filepath,
+            $_template->source->name,
+            $_template->cache_id,
+            $_template->compile_id,
+            $_template->properties['cache_lifetime'],
+            $content
+        );
+    }
+
+    /**
+     * Empty cache
+     *
+     * @param Smarty  $smarty   Smarty object
+     * @param integer $exp_time expiration time (number of seconds, not timestamp)
+     * @return integer number of cache files deleted
+     */
+    public function clearAll(Smarty $smarty, $exp_time=null)
+    {
+        $this->cache = array();
+        return $this->delete(null, null, null, $exp_time);
+    }
+
+    /**
+     * Empty cache for a specific template
+     *
+     * @param Smarty  $smarty        Smarty object
+     * @param string  $resource_name template name
+     * @param string  $cache_id      cache id
+     * @param string  $compile_id    compile id
+     * @param integer $exp_time      expiration time (number of seconds, not timestamp)
+     * @return integer number of cache files deleted
+     */
+    public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
+    {
+        $this->cache = array();
+        return $this->delete($resource_name, $cache_id, $compile_id, $exp_time);
+    }
+    
+    /**
+     * Check is cache is locked for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if cache is locked
+     */
+    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $id = $cached->filepath;
+        $name = $cached->source->name . '.lock';
+        
+        $mtime = $this->fetchTimestamp($id, $name, null, null);
+        if ($mtime === null) {
+            $this->fetch($id, $name, null, null, $content, $mtime);
+        }
+        
+        return $mtime && time() - $mtime < $smarty->locking_timeout;
+    }
+
+    /**
+     * Lock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = true;
+        
+        $id = $cached->filepath;
+        $name = $cached->source->name . '.lock';
+        $this->save($id, $name, null, null, $smarty->locking_timeout, '');
+    }
+
+    /**
+     * Unlock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = false;
+        
+        $id = $cached->filepath;
+        $name = $cached->source->name . '.lock';
+        $this->delete($name, null, null, null);
+    }
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_keyvaluestore.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_keyvaluestore.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_cacheresource_keyvaluestore.php	(revision 345)
@@ -0,0 +1,463 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+
+/**
+ * Smarty Cache Handler Base for Key/Value Storage Implementations
+ *
+ * This class implements the functionality required to use simple key/value stores
+ * for hierarchical cache groups. key/value stores like memcache or APC do not support
+ * wildcards in keys, therefore a cache group cannot be cleared like "a|*" - which
+ * is no problem to filesystem and RDBMS implementations.
+ *
+ * This implementation is based on the concept of invalidation. While one specific cache
+ * can be identified and cleared, any range of caches cannot be identified. For this reason
+ * each level of the cache group hierarchy can have its own value in the store. These values
+ * are nothing but microtimes, telling us when a particular cache group was cleared for the
+ * last time. These keys are evaluated for every cache read to determine if the cache has
+ * been invalidated since it was created and should hence be treated as inexistent.
+ *
+ * Although deep hierarchies are possible, they are not recommended. Try to keep your
+ * cache groups as shallow as possible. Anything up 3-5 parents should be ok. So
+ * Â»a|b|cÂ« is a good depth where Â»a|b|c|d|e|f|g|h|i|j|kÂ« isn't. Try to join correlating
+ * cache groups: if your cache groups look somewhat like Â»a|b|$page|$items|$whateverÂ«
+ * consider using Â»a|b|c|$page-$items-$whateverÂ« instead.
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Rodney Rehm
+ */
+abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
+
+    /**
+     * cache for contents
+     * @var array
+     */
+    protected $contents = array();
+    /**
+     * cache for timestamps
+     * @var array
+     */
+    protected $timestamps = array();
+
+    /**
+     * populate Cached Object with meta data from Resource
+     *
+     * @param Smarty_Template_Cached   $cached    cached object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
+    {
+        $cached->filepath = $_template->source->uid
+                . '#' . $this->sanitize($cached->source->name)
+                . '#' . $this->sanitize($cached->cache_id)
+                . '#' . $this->sanitize($cached->compile_id);
+
+        $this->populateTimestamp($cached);
+    }
+
+    /**
+     * populate Cached Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Cached $cached cached object
+     * @return void
+     */
+    public function populateTimestamp(Smarty_Template_Cached $cached)
+    {
+        if (!$this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $content, $timestamp, $cached->source->uid)) {
+            return;
+        }
+        $cached->content = $content;
+        $cached->timestamp = (int) $timestamp;
+        $cached->exists = $cached->timestamp;
+    }
+
+    /**
+     * Read the cached template and process the header
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if the cached content does not exist
+     */
+    public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
+    {
+        if (!$cached) {
+            $cached = $_template->cached;
+        }
+        $content = $cached->content ? $cached->content : null;
+        $timestamp = $cached->timestamp ? $cached->timestamp : null;
+        if ($content === null || !$timestamp) {
+            if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) {
+                return false;
+            }
+        }
+        if (isset($content)) {
+            $_smarty_tpl = $_template;
+            eval("?>" . $content);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Write the rendered template output to cache
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param string $content content to cache
+     * @return boolean success
+     */
+    public function writeCachedContent(Smarty_Internal_Template $_template, $content)
+    {
+        $this->addMetaTimestamp($content);
+        return $this->write(array($_template->cached->filepath => $content), $_template->properties['cache_lifetime']);
+    }
+
+    /**
+     * Empty cache
+     *
+     * {@internal the $exp_time argument is ignored altogether }}
+     *
+     * @param Smarty  $smarty   Smarty object
+     * @param integer $exp_time expiration time [being ignored]
+     * @return integer number of cache files deleted [always -1]
+     * @uses purge() to clear the whole store
+     * @uses invalidate() to mark everything outdated if purge() is inapplicable
+     */
+    public function clearAll(Smarty $smarty, $exp_time=null)
+    {
+        if (!$this->purge()) {
+            $this->invalidate(null);
+        }
+        return -1;
+    }
+
+    /**
+     * Empty cache for a specific template
+     *
+     * {@internal the $exp_time argument is ignored altogether}}
+     *
+     * @param Smarty  $smarty        Smarty object
+     * @param string  $resource_name template name
+     * @param string  $cache_id      cache id
+     * @param string  $compile_id    compile id
+     * @param integer $exp_time      expiration time [being ignored]
+     * @return integer number of cache files deleted [always -1]
+     * @uses buildCachedFilepath() to generate the CacheID
+     * @uses invalidate() to mark CacheIDs parent chain as outdated
+     * @uses delete() to remove CacheID from cache
+     */
+    public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
+    {
+        $uid = $this->getTemplateUid($smarty, $resource_name, $cache_id, $compile_id);
+        $cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' . $this->sanitize($compile_id);
+        $this->delete(array($cid));
+        $this->invalidate($cid, $resource_name, $cache_id, $compile_id, $uid);
+        return -1;
+    }
+    /**
+     * Get template's unique ID
+     *
+     * @param Smarty $smarty        Smarty object
+     * @param string $resource_name template name
+     * @param string $cache_id      cache id
+     * @param string $compile_id    compile id
+     * @return string filepath of cache file
+     */
+    protected function getTemplateUid(Smarty $smarty, $resource_name, $cache_id, $compile_id)
+    {
+        $uid = '';
+        if (isset($resource_name)) {
+            $tpl = new $smarty->template_class($resource_name, $smarty);
+            if ($tpl->source->exists) {
+                $uid = $tpl->source->uid;
+            }
+            
+            // remove from template cache
+            if ($smarty->allow_ambiguous_resources) {
+                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+            } else {
+                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+            }
+            if (isset($_templateId[150])) {
+                $_templateId = sha1($_templateId);
+            }
+            unset($smarty->template_objects[$_templateId]);
+        }
+        return $uid;
+    }
+
+    /**
+     * Sanitize CacheID components
+     *
+     * @param string $string CacheID component to sanitize
+     * @return string sanitized CacheID component
+     */
+    protected function sanitize($string)
+    {
+        // some poeple smoke bad weed
+        $string = trim($string, '|');
+        if (!$string) {
+            return null;
+        }
+        return preg_replace('#[^\w\|]+#S', '_', $string);
+    }
+
+    /**
+     * Fetch and prepare a cache object.
+     *
+     * @param string  $cid           CacheID to fetch
+     * @param string  $resource_name template name
+     * @param string  $cache_id      cache id
+     * @param string  $compile_id    compile id
+     * @param string  $content       cached content
+     * @param integer &$timestamp    cached timestamp (epoch)
+     * @param string  $resource_uid  resource's uid
+     * @return boolean success
+     */
+    protected function fetch($cid, $resource_name = null, $cache_id = null, $compile_id = null, &$content = null, &$timestamp = null, $resource_uid = null)
+    {
+        $t = $this->read(array($cid));
+        $content = !empty($t[$cid]) ? $t[$cid] : null;
+        $timestamp = null;
+
+        if ($content && ($timestamp = $this->getMetaTimestamp($content))) {
+            $invalidated = $this->getLatestInvalidationTimestamp($cid, $resource_name, $cache_id, $compile_id, $resource_uid);
+            if ($invalidated > $timestamp) {
+                $timestamp = null;
+                $content = null;
+            }
+        }
+
+        return !!$content;
+    }
+
+    /**
+     * Add current microtime to the beginning of $cache_content
+     *
+     * {@internal the header uses 8 Bytes, the first 4 Bytes are the seconds, the second 4 Bytes are the microseconds}}
+     *
+     * @param string &$content the content to be cached
+     */
+    protected function addMetaTimestamp(&$content)
+    {
+        $mt = explode(" ", microtime());
+        $ts = pack("NN", $mt[1], (int) ($mt[0] * 100000000));
+        $content = $ts . $content;
+    }
+
+    /**
+     * Extract the timestamp the $content was cached
+     *
+     * @param string &$content the cached content
+     * @return float the microtime the content was cached
+     */
+    protected function getMetaTimestamp(&$content)
+    {
+        $s = unpack("N", substr($content, 0, 4));
+        $m = unpack("N", substr($content, 4, 4));
+        $content = substr($content, 8);
+        return $s[1] + ($m[1] / 100000000);
+    }
+
+    /**
+     * Invalidate CacheID
+     *
+     * @param string $cid           CacheID
+     * @param string $resource_name template name
+     * @param string $cache_id      cache id
+     * @param string $compile_id    compile id
+     * @param string $resource_uid  source's uid
+     * @return void
+     */
+    protected function invalidate($cid = null, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
+    {
+        $now = microtime(true);
+        $key = null;
+        // invalidate everything
+        if (!$resource_name && !$cache_id && !$compile_id) {
+            $key = 'IVK#ALL';
+        }
+        // invalidate all caches by template
+        else if ($resource_name && !$cache_id && !$compile_id) {
+            $key = 'IVK#TEMPLATE#' . $resource_uid . '#' . $this->sanitize($resource_name);
+        }
+        // invalidate all caches by cache group
+        else if (!$resource_name && $cache_id && !$compile_id) {
+            $key = 'IVK#CACHE#' . $this->sanitize($cache_id);
+        }
+        // invalidate all caches by compile id
+        else if (!$resource_name && !$cache_id && $compile_id) {
+            $key = 'IVK#COMPILE#' . $this->sanitize($compile_id);
+        }
+        // invalidate by combination
+        else {
+            $key = 'IVK#CID#' . $cid;
+        }
+        $this->write(array($key => $now));
+    }
+
+    /**
+     * Determine the latest timestamp known to the invalidation chain
+     *
+     * @param string $cid           CacheID to determine latest invalidation timestamp of
+     * @param string $resource_name template name
+     * @param string $cache_id      cache id
+     * @param string $compile_id    compile id
+     * @param string $resource_uid  source's filepath
+     * @return float the microtime the CacheID was invalidated
+     */
+    protected function getLatestInvalidationTimestamp($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
+    {
+        // abort if there is no CacheID
+        if (false && !$cid) {
+            return 0;
+        }
+        // abort if there are no InvalidationKeys to check
+        if (!($_cid = $this->listInvalidationKeys($cid, $resource_name, $cache_id, $compile_id, $resource_uid))) {
+            return 0;
+        }
+        
+        // there are no InValidationKeys
+        if (!($values = $this->read($_cid))) {
+            return 0;
+        }
+        // make sure we're dealing with floats
+        $values = array_map('floatval', $values);
+        return max($values);
+    }
+
+    /**
+     * Translate a CacheID into the list of applicable InvalidationKeys.
+     *
+     * Splits "some|chain|into|an|array" into array( '#clearAll#', 'some', 'some|chain', 'some|chain|into', ... )
+     *
+     * @param string $cid           CacheID to translate
+     * @param string $resource_name template name
+     * @param string $cache_id      cache id
+     * @param string $compile_id    compile id
+     * @param string $resource_uid  source's filepath
+     * @return array list of InvalidationKeys
+     * @uses $invalidationKeyPrefix to prepend to each InvalidationKey
+     */
+    protected function listInvalidationKeys($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
+    {
+        $t = array('IVK#ALL');
+        $_name = $_compile = '#';
+        if ($resource_name) {
+            $_name .= $resource_uid . '#' . $this->sanitize($resource_name);
+            $t[] = 'IVK#TEMPLATE' . $_name;
+        }
+        if ($compile_id) {
+            $_compile .= $this->sanitize($compile_id);
+            $t[] = 'IVK#COMPILE' . $_compile;
+        }
+        $_name .= '#';
+        // some poeple smoke bad weed
+        $cid = trim($cache_id, '|');
+        if (!$cid) {
+            return $t;
+        }
+        $i = 0;
+        while (true) {
+            // determine next delimiter position
+            $i = strpos($cid, '|', $i);
+            // add complete CacheID if there are no more delimiters
+            if ($i === false) {
+                $t[] = 'IVK#CACHE#' . $cid;
+                $t[] = 'IVK#CID' . $_name . $cid . $_compile;
+                $t[] = 'IVK#CID' . $_name . $_compile;
+                break;
+            }
+            $part = substr($cid, 0, $i);
+            // add slice to list
+            $t[] = 'IVK#CACHE#' . $part;
+            $t[] = 'IVK#CID' . $_name . $part . $_compile;
+            // skip past delimiter position
+            $i++;
+        }
+        return $t;
+    }
+
+    /**
+     * Check is cache is locked for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if cache is locked
+     */
+    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $key = 'LOCK#' . $cached->filepath;
+        $data = $this->read(array($key));
+        return $data && time() - $data[$key] < $smarty->locking_timeout;
+    }
+
+    /**
+     * Lock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = true;
+        $key = 'LOCK#' . $cached->filepath;
+        $this->write(array($key => time()), $smarty->locking_timeout);
+    }
+
+    /**
+     * Unlock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = false;
+        $key = 'LOCK#' . $cached->filepath;
+        $this->delete(array($key));
+    }
+
+    /**
+     * Read values for a set of keys from cache
+     *
+     * @param array $keys list of keys to fetch
+     * @return array list of values with the given keys used as indexes
+     */
+    protected abstract function read(array $keys);
+
+    /**
+     * Save values for a set of keys to cache
+     *
+     * @param array $keys   list of values to save
+     * @param int   $expire expiration time
+     * @return boolean true on success, false on failure
+     */
+    protected abstract function write(array $keys, $expire=null);
+
+    /**
+     * Remove values from cache
+     *
+     * @param array $keys list of keys to delete
+     * @return boolean true on success, false on failure
+     */
+    protected abstract function delete(array $keys);
+
+    /**
+     * Remove *all* values from cache
+     *
+     * @return boolean true on success, false on failure
+     */
+    protected function purge()
+    {
+        return false;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_config_source.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_config_source.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_config_source.php	(revision 345)
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+
+/**
+ * Smarty Resource Data Object
+ *
+ * Meta Data Container for Config Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ *
+ * @property string $content
+ * @property int    $timestamp
+ * @property bool   $exists
+ */
+class Smarty_Config_Source extends Smarty_Template_Source {
+
+    /**
+     * create Config Object container
+     *
+     * @param Smarty_Resource $handler          Resource Handler this source object communicates with
+     * @param Smarty          $smarty           Smarty instance this source object belongs to
+     * @param string          $resource         full config_resource
+     * @param string          $type             type of resource
+     * @param string          $name             resource name
+     * @param string          $unique_resource  unqiue resource name
+     */
+    public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource)
+    {
+        $this->handler = $handler; // Note: prone to circular references
+
+        // Note: these may be ->config_compiler_class etc in the future
+        //$this->config_compiler_class = $handler->config_compiler_class;
+        //$this->config_lexer_class = $handler->config_lexer_class;
+        //$this->config_parser_class = $handler->config_parser_class;
+
+        $this->smarty = $smarty;
+        $this->resource = $resource;
+        $this->type = $type;
+        $this->name = $name;
+        $this->unique_resource = $unique_resource;
+    }
+
+    /**
+     * <<magic>> Generic setter.
+     *
+     * @param string $property_name valid: content, timestamp, exists
+     * @param mixed  $value         newly assigned value (not check for correct type)
+     * @throws SmartyException when the given property name is not valid
+     */
+    public function __set($property_name, $value)
+    {
+        switch ($property_name) {
+            case 'content':
+            case 'timestamp':
+            case 'exists':
+                $this->$property_name = $value;
+                break;
+
+            default:
+                throw new SmartyException("invalid config property '$property_name'.");
+        }
+    }
+
+    /**
+     * <<magic>> Generic getter.
+     *
+     * @param string $property_name valid: content, timestamp, exists
+     * @throws SmartyException when the given property name is not valid
+     */
+    public function __get($property_name)
+    {
+        switch ($property_name) {
+            case 'timestamp':
+            case 'exists':
+                $this->handler->populateTimestamp($this);
+                return $this->$property_name;
+
+            case 'content':
+                return $this->content = $this->handler->getContent($this);
+
+            default:
+                throw new SmartyException("config property '$property_name' does not exist.");
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_cacheresource_file.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_cacheresource_file.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_cacheresource_file.php	(revision 345)
@@ -0,0 +1,264 @@
+<?php
+/**
+ * Smarty Internal Plugin CacheResource File
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * This class does contain all necessary methods for the HTML cache on file system
+ *
+ * Implements the file system as resource for the HTML cache Version ussing nocache inserts.
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
+
+    /**
+     * populate Cached Object with meta data from Resource
+     *
+     * @param Smarty_Template_Cached   $cached    cached object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
+    {
+        $_source_file_path = str_replace(':', '.', $_template->source->filepath);
+        $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
+        $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
+        $_filepath = $_template->source->uid;
+        // if use_sub_dirs, break file into directories
+        if ($_template->smarty->use_sub_dirs) {
+            $_filepath = substr($_filepath, 0, 2) . DS
+                . substr($_filepath, 2, 2) . DS
+                . substr($_filepath, 4, 2) . DS
+                . $_filepath;
+        }
+        $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
+        if (isset($_cache_id)) {
+            $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
+        } else {
+            $_cache_id = '';
+        }
+        if (isset($_compile_id)) {
+            $_compile_id = $_compile_id . $_compile_dir_sep;
+        } else {
+            $_compile_id = '';
+        }
+        $_cache_dir = $_template->smarty->getCacheDir();
+        if ($_template->smarty->cache_locking) {
+            // create locking file name
+            // relative file name?
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
+                $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
+            } else {
+                $_lock_dir = $_cache_dir;
+            }
+            $cached->lock_id = $_lock_dir.sha1($_cache_id.$_compile_id.$_template->source->uid).'.lock';
+        }
+        $cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php';
+        $cached->timestamp = @filemtime($cached->filepath);
+        $cached->exists = !!$cached->timestamp;
+    }
+
+    /**
+     * populate Cached Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Cached $cached cached object
+     * @return void
+     */
+    public function populateTimestamp(Smarty_Template_Cached $cached)
+    {
+        $cached->timestamp = @filemtime($cached->filepath);
+        $cached->exists = !!$cached->timestamp;
+    }
+
+    /**
+     * Read the cached template and process its header
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if the cached content does not exist
+     */
+    public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
+    {
+        $_smarty_tpl = $_template;
+        return @include $_template->cached->filepath;
+    }
+
+    /**
+     * Write the rendered template output to cache
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param string                   $content   content to cache
+     * @return boolean success
+     */
+    public function writeCachedContent(Smarty_Internal_Template $_template, $content)
+    {
+        if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
+            $_template->cached->timestamp = filemtime($_template->cached->filepath);
+            $_template->cached->exists = !!$_template->cached->timestamp;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Empty cache
+     *
+     * @param Smarty_Internal_Template $_template template object
+     * @param integer                  $exp_time  expiration time (number of seconds, not timestamp)
+     * @return integer number of cache files deleted
+     */
+    public function clearAll(Smarty $smarty, $exp_time = null)
+    {
+        return $this->clear($smarty, null, null, null, $exp_time);
+    }
+
+    /**
+     * Empty cache for a specific template
+     *
+     * @param Smarty  $_template     template object
+     * @param string  $resource_name template name
+     * @param string  $cache_id      cache id
+     * @param string  $compile_id    compile id
+     * @param integer $exp_time      expiration time (number of seconds, not timestamp)
+     * @return integer number of cache files deleted
+    */
+    public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
+    {
+        $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
+        $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+        $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
+        $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
+        $_dir = $smarty->getCacheDir();
+        $_dir_length = strlen($_dir);
+        if (isset($_cache_id)) {
+            $_cache_id_parts = explode('|', $_cache_id);
+            $_cache_id_parts_count = count($_cache_id_parts);
+            if ($smarty->use_sub_dirs) {
+                foreach ($_cache_id_parts as $id_part) {
+                    $_dir .= $id_part . DS;
+                }
+            }
+        }
+        if (isset($resource_name)) {
+            $_save_stat = $smarty->caching;
+            $smarty->caching = true;
+            $tpl = new $smarty->template_class($resource_name, $smarty);
+            $smarty->caching = $_save_stat;
+
+            // remove from template cache
+            $tpl->source; // have the template registered before unset()
+            if ($smarty->allow_ambiguous_resources) {
+                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+            } else {
+                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+            }
+            if (isset($_templateId[150])) {
+                $_templateId = sha1($_templateId);
+            }
+            unset($smarty->template_objects[$_templateId]);
+
+            if ($tpl->source->exists) {
+                $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
+            } else {
+                return 0;
+            }
+        }
+        $_count = 0;
+        $_time = time();
+        if (file_exists($_dir)) {
+            $_cacheDirs = new RecursiveDirectoryIterator($_dir);
+            $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
+            foreach ($_cache as $_file) {
+                if (substr($_file->getBasename(),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
+                // directory ?
+                if ($_file->isDir()) {
+                    if (!$_cache->isDot()) {
+                        // delete folder if empty
+                        @rmdir($_file->getPathname());
+                    }
+                } else {
+                    $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
+                    $_parts_count = count($_parts);
+                    // check name
+                    if (isset($resource_name)) {
+                        if ($_parts[$_parts_count-1] != $_resourcename_parts) {
+                            continue;
+                        }
+                    }
+                    // check compile id
+                    if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) {
+                        continue;
+                    }
+                    // check cache id
+                    if (isset($_cache_id)) {
+                        // count of cache id parts
+                        $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
+                        if ($_parts_count < $_cache_id_parts_count) {
+                            continue;
+                        }
+                        for ($i = 0; $i < $_cache_id_parts_count; $i++) {
+                            if ($_parts[$i] != $_cache_id_parts[$i]) continue 2;
+                        }
+                    }
+                    // expired ?
+                    if (isset($exp_time) && $_time - @filemtime($_file) < $exp_time) {
+                        continue;
+                    }
+                    $_count += @unlink((string) $_file) ? 1 : 0;
+                }
+            }
+        }
+        return $_count;
+    }
+
+    /**
+     * Check is cache is locked for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     * @return booelan true or false if cache is locked
+     */
+    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+            clearstatcache(true, $cached->lock_id);
+        } else {
+            clearstatcache();
+        }
+        $t = @filemtime($cached->lock_id);
+        return $t && (time() - $t < $smarty->locking_timeout);
+    }
+
+    /**
+     * Lock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = true;
+        touch($cached->lock_id);
+    }
+
+    /**
+     * Unlock cache for this template
+     *
+     * @param Smarty $smarty Smarty object
+     * @param Smarty_Template_Cached $cached cached object
+     */
+    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
+    {
+        $cached->is_locked = false;
+        @unlink($cached->lock_id);
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_append.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_append.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_append.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Append
+ *
+ * Compiles the {append} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Append Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign {
+
+    /**
+     * Compiles code for the {append} tag
+     *
+     * @param array $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // the following must be assigned at runtime because it will be overwritten in parent class
+        $this->required_attributes = array('var', 'value');
+        $this->shorttag_order = array('var', 'value');
+        $this->optional_attributes = array('scope', 'index');
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // map to compile assign attributes
+        if (isset($_attr['index'])) {
+            $_params['smarty_internal_index'] = '[' . $_attr['index'] . ']';
+            unset($_attr['index']);
+        } else {
+            $_params['smarty_internal_index'] = '[]';
+        }
+        $_new_attr = array();
+        foreach ($_attr as $key => $value) {
+            $_new_attr[] = array($key => $value);
+        }
+        // call compile assign
+        return parent::compile($_new_attr, $compiler, $_params);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_assign.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_assign.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_assign.php	(revision 345)
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Assign
+ *
+ * Compiles the {assign} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Assign Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {assign} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
+        $this->required_attributes = array('var', 'value');
+        $this->shorttag_order = array('var', 'value');
+        $this->optional_attributes = array('scope');
+        $_nocache = 'null';
+        $_scope = Smarty::SCOPE_LOCAL;
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // nocache ?
+        if ($compiler->tag_nocache || $compiler->nocache) {
+            $_nocache = 'true';
+            // create nocache var to make it know for further compiling
+            $compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true);
+        }
+        // scope setup
+        if (isset($_attr['scope'])) {
+            $_attr['scope'] = trim($_attr['scope'], "'\"");
+            if ($_attr['scope'] == 'parent') {
+                $_scope = Smarty::SCOPE_PARENT;
+            } elseif ($_attr['scope'] == 'root') {
+                $_scope = Smarty::SCOPE_ROOT;
+            } elseif ($_attr['scope'] == 'global') {
+                $_scope = Smarty::SCOPE_GLOBAL;
+            } else {
+                $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
+            }
+        }
+        // compiled output
+        if (isset($parameter['smarty_internal_index'])) {
+            $output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
+        } else {
+            $output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
+        }
+        if ($_scope == Smarty::SCOPE_PARENT) {
+            $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
+        } elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) {
+            $output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }";
+        }
+        if ( $_scope == Smarty::SCOPE_GLOBAL) {
+            $output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
+        }
+        $output .= '?>';
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_block.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_block.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_block.php	(revision 345)
@@ -0,0 +1,264 @@
+<?php
+/**
+* Smarty Internal Plugin Compile Block
+*
+* Compiles the {block}{/block} tags
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+/**
+* Smarty Internal Plugin Compile Block Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
+
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $required_attributes = array('name');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $shorttag_order = array('name', 'hide');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $optional_attributes = array('hide');
+
+    /**
+    * Compiles code for the {block} tag
+    *
+    * @param array  $args     array with attributes from parser
+    * @param object $compiler compiler object
+    * @return boolean true
+    */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        $save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
+        $this->openTag($compiler, 'block', $save);
+        if ($_attr['nocache'] == true) {
+            $compiler->nocache = true;
+        }
+        // set flag for {block} tag
+        $compiler->inheritance = true;
+        // must merge includes
+        $compiler->smarty->merge_compiled_includes = true;
+
+        $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
+        $compiler->has_code = false;
+        return true;
+    }
+
+    /**
+    * Save or replace child block source by block name during parsing
+    *
+    * @param string $block_content     block source content
+    * @param string $block_tag         opening block tag
+    * @param object $template          template object
+    * @param string $filepath          filepath of template source
+    */
+    public static function saveBlockData($block_content, $block_tag, $template, $filepath)
+    {
+        $_rdl = preg_quote($template->smarty->right_delimiter);
+        $_ldl = preg_quote($template->smarty->left_delimiter);
+        if ($template->smarty->auto_literal) {
+            $al = '\s*';
+        } else {
+            $al = '';
+        }
+        if (0 == preg_match("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
+            $error_text = 'Syntax Error in template "' . $template->source->filepath . '"   "' . htmlspecialchars($block_tag) . '" illegal options';
+            throw new SmartyCompilerException($error_text);
+        } else {
+            $_name = trim($_match[3], '\'"');
+            if ($_match[8] != 'hide' || isset($template->block_data[$_name])) {        // replace {$smarty.block.child}
+                // do we have {$smart.block.child} in nested {block} tags?
+                if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?{$_ldl}{$al}/block{$_rdl})!", $block_content, $_match2)) {
+                    foreach($_match2[3] as $name) {
+                        // get it's replacement
+                        $_name2 = trim($name, '\'"');
+                        if (isset($template->block_data[$_name2])) {
+                            $replacement = $template->block_data[$_name2]['source'];
+                        } else {
+                            $replacement = '';
+                        }
+                        // replace {$smarty.block.child} tag
+                        $search = array("%({$_ldl}{$al}block[\s\S]*?{$name}[\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?{$_ldl}{$al}/block{$_rdl})%","/§§§child§§§/");
+                        $replace = array('\2§§§child§§§', $replacement);
+                        $block_content = preg_replace($search, $replace , $block_content);
+                    }
+                }
+                // do we have not nested {$smart.block.child}
+                if (0 != preg_match("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $block_content, $_match2)) {
+                    // get child replacement for this block
+                    if (isset($template->block_data[$_name])) {
+                        $replacement = $template->block_data[$_name]['source'];
+                        unset($template->block_data[$_name]);
+                    } else {
+                        $replacement = '';
+                    }
+                    $block_content = preg_replace("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $replacement, $block_content);
+                }
+                if (isset($template->block_data[$_name])) {
+                    if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
+                        $template->block_data[$_name]['source'] =
+                        str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
+                    } elseif ($template->block_data[$_name]['mode'] == 'prepend') {
+                        $template->block_data[$_name]['source'] .= $block_content;
+                    } elseif ($template->block_data[$_name]['mode'] == 'append') {
+                        $template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source'];
+                    }
+                } else {
+                    $template->block_data[$_name]['source'] = $block_content;
+                    $template->block_data[$_name]['file'] = $filepath;
+                }
+                if ($_match[6] == 'append') {
+                    $template->block_data[$_name]['mode'] = 'append';
+                } elseif ($_match[6] == 'prepend') {
+                    $template->block_data[$_name]['mode'] = 'prepend';
+                } else {
+                    $template->block_data[$_name]['mode'] = 'replace';
+                }
+            }
+        }
+    }
+
+    /**
+    * Compile saved child block source
+    *
+    * @param object $compiler  compiler object
+    * @param string $_name     optional name of child block
+    * @return string   compiled code of schild block
+    */
+    public static function compileChildBlock($compiler, $_name = null)
+    {
+        $_output = '';
+        // if called by {$smarty.block.child} we must search the name of enclosing {block}
+        if ($_name == null) {
+            $stack_count = count($compiler->_tag_stack);
+            while (--$stack_count >= 0) {
+                if ($compiler->_tag_stack[$stack_count][0] == 'block') {
+                    $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'] ,"'\"");
+                    break;
+                }
+            }
+            // flag that child is already compile by {$smarty.block.child} inclusion
+            $compiler->template->block_data[$_name]['compiled'] = true;
+        }
+        if ($_name == null) {
+            $compiler->trigger_template_error('{$smarty.block.child} used out of context', $compiler->lex->taglineno);
+        }
+        // undefined child?
+        if (!isset($compiler->template->block_data[$_name]['source'])) {
+            return '';
+        }
+        $_tpl = new Smarty_Internal_template ('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
+        $compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
+        $_tpl->variable_filters = $compiler->template->variable_filters;
+        $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
+        $_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
+        $_tpl->allow_relative_path = true;
+        if ($compiler->nocache) {
+            $_tpl->compiler->forceNocache = 2;
+        } else {
+            $_tpl->compiler->forceNocache = 1;
+        }
+        $_tpl->compiler->suppressHeader = true;
+        $_tpl->compiler->suppressTemplatePropertyHeader = true;
+        $_tpl->compiler->suppressMergedTemplates = true;
+        if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
+            $_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl));
+        } elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
+            $_output = $_tpl->compiler->compileTemplate($_tpl) . $compiler->parser->current_buffer->to_smarty_php();
+        } elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
+            $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl);
+        } elseif (!empty($compiler->template->block_data[$_name])) {
+            $_output = $_tpl->compiler->compileTemplate($_tpl);
+        }
+        $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
+        $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
+        $compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
+        $compiler->template->variable_filters = $_tpl->variable_filters;
+        if ($_tpl->has_nocache_code) {
+            $compiler->template->has_nocache_code = true;
+        }
+        foreach($_tpl->required_plugins as $code => $tmp1) {
+            foreach($tmp1 as $name => $tmp) {
+                foreach($tmp as $type => $data) {
+                    $compiler->template->required_plugins[$code][$name][$type] = $data;
+                }
+            }
+        }
+        unset($_tpl);
+        return $_output;
+    }
+
+}
+
+/**
+* Smarty Internal Plugin Compile BlockClose Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
+
+    /**
+    * Compiles code for the {/block} tag
+    *
+    * @param array  $args     array with attributes from parser
+    * @param object $compiler compiler object
+    * @return string compiled code
+    */
+    public function compile($args, $compiler)
+    {
+        $compiler->has_code = true;
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        $saved_data = $this->closeTag($compiler, array('block'));
+        $_name = trim($saved_data[0]['name'], "\"'");
+        if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
+            // restore to status before {block} tag as new subtemplate code of parent {block} is not needed
+            $compiler->merged_templates = $saved_data[4];
+            $compiler->smarty->merged_templates_func = $saved_data[5];
+            $compiler->template->properties = $saved_data[6];
+            $compiler->template->has_nocache_code = $saved_data[7];
+            $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
+        } else {
+            if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) {
+                $_output = '';
+            } else {
+                $_output = $compiler->parser->current_buffer->to_smarty_php();
+            }
+            unset ($compiler->template->block_data[$_name]['compiled']);
+        }
+        // reset flags
+        $compiler->parser->current_buffer = $saved_data[1];
+        $compiler->nocache = $saved_data[2];
+        $compiler->smarty->merge_compiled_includes = $saved_data[3];
+        // reset flag for {block} tag
+        $compiler->inheritance = false;
+        // $_output content has already nocache code processed
+        $compiler->suppressNocacheProcessing = true;
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_break.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_break.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_break.php	(revision 345)
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Break
+ *
+ * Compiles the {break} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+/**
+ * Smarty Internal Plugin Compile Break Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('levels');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('levels');
+
+    /**
+     * Compiles code for the {break} tag
+     *
+     * @param array  $args array with attributes from parser
+     * @param object $compiler   compiler object
+     * @param array  $parameter  array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+
+        if (isset($_attr['levels'])) {
+            if (!is_numeric($_attr['levels'])) {
+                $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+            }
+            $_levels = $_attr['levels'];
+        } else {
+            $_levels = 1;
+        }
+        $level_count = $_levels;
+        $stack_count = count($compiler->_tag_stack) - 1;
+        while ($level_count > 0 && $stack_count >= 0) {
+            if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+                $level_count--;
+            }
+            $stack_count--;
+        }
+        if ($level_count != 0) {
+            $compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
+        }
+        $compiler->has_code = true;
+        return "<?php break {$_levels}?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_call.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_call.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_call.php	(revision 345)
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function_Call
+ *
+ * Compiles the calls of user defined tags defined by {function}
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function_Call Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles the calls of user defined tags defined by {function}
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // save possible attributes
+        if (isset($_attr['assign'])) {
+            // output will be stored in a smarty variable instead of beind displayed
+            $_assign = $_attr['assign'];
+        }
+        $_name = $_attr['name'];
+        if ($compiler->compiles_template_function) {
+            $compiler->called_functions[] = trim($_name, "'\"");
+        }
+        unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
+        // set flag (compiled code of {function} must be included in cache file
+        if ($compiler->nocache || $compiler->tag_nocache) {
+            $_nocache = 'true';
+        } else {
+            $_nocache = 'false';
+        }
+        $_paramsArray = array();
+        foreach ($_attr as $_key => $_value) {
+            if (is_int($_key)) {
+                $_paramsArray[] = "$_key=>$_value";
+            } else {
+                $_paramsArray[] = "'$_key'=>$_value";
+            }
+        }
+        if (isset($compiler->template->properties['function'][$_name]['parameter'])) {
+            foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
+                if (!isset($_attr[$_key])) {
+                    if (is_int($_key)) {
+                        $_paramsArray[] = "$_key=>$_value";
+                    } else {
+                        $_paramsArray[] = "'$_key'=>$_value";
+                    }
+                }
+            }
+        } elseif (isset($compiler->smarty->template_functions[$_name]['parameter'])) {
+            foreach ($compiler->smarty->template_functions[$_name]['parameter'] as $_key => $_value) {
+                if (!isset($_attr[$_key])) {
+                    if (is_int($_key)) {
+                        $_paramsArray[] = "$_key=>$_value";
+                    } else {
+                        $_paramsArray[] = "'$_key'=>$_value";
+                    }
+                }
+            }
+        }
+        //varibale name?
+        if (!(strpos($_name, '$') === false)) {
+            $call_cache = $_name;
+            $call_function = '$tmp = "smarty_template_function_".' . $_name . '; $tmp';
+        } else {
+            $_name = trim($_name, "'\"");
+            $call_cache = "'{$_name}'";
+            $call_function = 'smarty_template_function_' . $_name;
+        }
+
+        $_params = 'array(' . implode(",", $_paramsArray) . ')';
+        $_hash = str_replace('-', '_', $compiler->template->properties['nocache_hash']);
+        // was there an assign attribute
+        if (isset($_assign)) {
+            if ($compiler->template->caching) {
+                $_output = "<?php ob_start(); Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
+            } else {
+                $_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
+            }
+        } else {
+            if ($compiler->template->caching) {
+                $_output = "<?php Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n";
+            } else {
+                $_output = "<?php {$call_function}(\$_smarty_tpl,{$_params});?>\n";
+            }
+        }
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_capture.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_capture.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_capture.php	(revision 345)
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Capture
+ *
+ * Compiles the {capture} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Capture Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('name', 'assign', 'append');
+
+    /**
+     * Compiles code for the {capture} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        $buffer = isset($_attr['name']) ? $_attr['name'] : "'default'";
+        $assign = isset($_attr['assign']) ? $_attr['assign'] : 'null';
+        $append = isset($_attr['append']) ? $_attr['append'] : 'null';
+
+        $compiler->_capture_stack[0][] = array($buffer, $assign, $append, $compiler->nocache);
+        // maybe nocache because of nocache variables
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+        $_output = "<?php \$_smarty_tpl->_capture_stack[0][] = array($buffer, $assign, $append); ob_start(); ?>";
+
+        return $_output;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Captureclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/capture} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+
+        list($buffer, $assign, $append, $compiler->nocache) = array_pop($compiler->_capture_stack[0]);
+
+        $_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_capture_stack[0]);\n";
+        $_output .= "if (!empty(\$_capture_buffer)) {\n";
+        $_output .= " if (isset(\$_capture_assign)) \$_smarty_tpl->assign(\$_capture_assign, ob_get_contents());\n";
+        $_output .= " if (isset( \$_capture_append)) \$_smarty_tpl->append( \$_capture_append, ob_get_contents());\n";
+        $_output .= " Smarty::\$_smarty_vars['capture'][\$_capture_buffer]=ob_get_clean();\n";
+        $_output .= "} else \$_smarty_tpl->capture_error();?>";
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_config_load.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_config_load.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_config_load.php	(revision 345)
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Config Load
+ *
+ * Compiles the {config load} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Config Load Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('file');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('file','section');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('section', 'scope');
+
+    /**
+     * Compiles code for the {config_load} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        static $_is_legal_scope = array('local' => true,'parent' => true,'root' => true,'global' => true);
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+
+
+        // save posible attributes
+        $conf_file = $_attr['file'];
+        if (isset($_attr['section'])) {
+            $section = $_attr['section'];
+        } else {
+            $section = 'null';
+        }
+        $scope = 'local';
+        // scope setup
+        if (isset($_attr['scope'])) {
+            $_attr['scope'] = trim($_attr['scope'], "'\"");
+            if (isset($_is_legal_scope[$_attr['scope']])) {
+                $scope = $_attr['scope'];
+           } else {
+                $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
+           }
+        }
+        // create config object
+        $_output = "<?php  \$_config = new Smarty_Internal_Config($conf_file, \$_smarty_tpl->smarty, \$_smarty_tpl);";
+        $_output .= "\$_config->loadConfigVars($section, '$scope'); ?>";
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_continue.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_continue.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_continue.php	(revision 345)
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Continue
+ *
+ * Compiles the {continue} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Continue Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('levels');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('levels');
+
+    /**
+     * Compiles code for the {continue} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+
+        if (isset($_attr['levels'])) {
+            if (!is_numeric($_attr['levels'])) {
+                $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+            }
+            $_levels = $_attr['levels'];
+        } else {
+            $_levels = 1;
+        }
+        $level_count = $_levels;
+        $stack_count = count($compiler->_tag_stack) - 1;
+        while ($level_count > 0 && $stack_count >= 0) {
+            if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+                $level_count--;
+            }
+            $stack_count--;
+        }
+        if ($level_count != 0) {
+            $compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
+        }
+        $compiler->has_code = true;
+        return "<?php continue {$_levels}?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_debug.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_debug.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_debug.php	(revision 345)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Debug
+ *
+ * Compiles the {debug} tag.
+ * It opens a window the the Smarty Debugging Console.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Debug Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {debug} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        // compile always as nocache
+        $compiler->tag_nocache = true;
+
+        // display debug template
+        $_output = "<?php \$_smarty_tpl->smarty->loadPlugin('Smarty_Internal_Debug'); Smarty_Internal_Debug::display_debug(\$_smarty_tpl); ?>";
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_eval.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_eval.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_eval.php	(revision 345)
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Eval
+ *
+ * Compiles the {eval} tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Eval Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('var');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('assign');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('var','assign');
+
+    /**
+     * Compiles code for the {eval} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        $this->required_attributes = array('var');
+        $this->optional_attributes = array('assign');
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        if (isset($_attr['assign'])) {
+              // output will be stored in a smarty variable instead of beind displayed
+            $_assign = $_attr['assign'];
+        }
+
+        // create template object
+        $_output = "\$_template = new {$compiler->smarty->template_class}('eval:'.".$_attr['var'].", \$_smarty_tpl->smarty, \$_smarty_tpl);";
+        //was there an assign attribute?
+        if (isset($_assign)) {
+            $_output .= "\$_smarty_tpl->assign($_assign,\$_template->fetch());";
+        } else {
+            $_output .= "echo \$_template->fetch();";
+        }
+        return "<?php $_output ?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_extends.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_extends.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_extends.php	(revision 345)
@@ -0,0 +1,121 @@
+<?php
+
+/**
+* Smarty Internal Plugin Compile extend
+*
+* Compiles the {extends} tag
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+/**
+* Smarty Internal Plugin Compile extend Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
+
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $required_attributes = array('file');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $shorttag_order = array('file');
+
+    /**
+    * Compiles code for the {extends} tag
+    *
+    * @param array  $args     array with attributes from parser
+    * @param object $compiler compiler object
+    * @return string compiled code
+    */
+    public function compile($args, $compiler)
+    {
+        static $_is_stringy = array('string' => true, 'eval' => true);
+        $this->_rdl = preg_quote($compiler->smarty->right_delimiter);
+        $this->_ldl = preg_quote($compiler->smarty->left_delimiter);
+        $filepath = $compiler->template->source->filepath;
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+
+        $_smarty_tpl = $compiler->template;
+        $include_file = null;
+        if (strpos($_attr['file'], '$_tmp') !== false) {
+            $compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
+        }
+        eval('$include_file = ' . $_attr['file'] . ';');
+        // create template object
+        $_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template);
+        // save file dependency
+        if (isset($_is_stringy[$_template->source->type])) {
+            $template_sha1 = sha1($include_file);
+        } else {
+            $template_sha1 = sha1($_template->source->filepath);
+        }
+        if (isset($compiler->template->properties['file_dependency'][$template_sha1])) {
+            $compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
+        }
+        $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
+        $_content = substr($compiler->template->source->content, $compiler->lex->counter - 1);
+        if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) !=
+        preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) {
+            $compiler->trigger_template_error('unmatched {block} {/block} pairs');
+        }
+        preg_match_all("!{$this->_ldl}block\s(.+?){$this->_rdl}|{$this->_ldl}/block{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
+        $_result_count = count($_result[0]);
+        $_start = 0;
+        while ($_start+1 < $_result_count) {
+            $_end = 0;
+            $_level = 1;
+            if (substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
+                $_start++;
+                continue;
+            }
+            while ($_level != 0) {
+                $_end++;
+                if (substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
+                    continue;
+                }
+                if (!strpos($_result[0][$_start + $_end][0], '/')) {
+                    $_level++;
+                } else {
+                    $_level--;
+                }
+            }
+            $_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
+            substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
+            Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath);
+            $_start = $_start + $_end + 1;
+        }
+        if ($_template->source->type == 'extends') {
+            $_template->block_data = $compiler->template->block_data;
+        }
+        $compiler->template->source->content = $_template->source->content;
+        if ($_template->source->type == 'extends') {
+            $compiler->template->block_data = $_template->block_data;
+            foreach ($_template->source->components as $key => $component) {
+                $compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type);
+            }
+        }
+        $compiler->template->source->filepath = $_template->source->filepath;
+        $compiler->abort_and_recompile = true;
+        return '';
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_for.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_for.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_for.php	(revision 345)
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile For
+ *
+ * Compiles the {for} {forelse} {/for} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile For Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {for} tag
+     *
+     * Smarty 3 does implement two different sytaxes:
+     *
+     * - {for $var in $array}
+     * For looping over arrays or iterators
+     *
+     * - {for $x=0; $x<$y; $x++}
+     * For general loops
+     *
+     * The parser is gereration different sets of attribute by which this compiler can
+     * determin which syntax is used.
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        if ($parameter == 0) {
+            $this->required_attributes = array('start', 'to');
+            $this->optional_attributes = array('max', 'step');
+        } else {
+            $this->required_attributes = array('start', 'ifexp', 'var', 'step');
+            $this->optional_attributes = array();
+        }
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        $output = "<?php ";
+        if ($parameter == 1) {
+            foreach ($_attr['start'] as $_statement) {
+                $output .= " \$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
+                $output .= " \$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value];\n";
+            }
+            $output .= "  if ($_attr[ifexp]){ for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$_attr[var]]->value$_attr[step]){\n";
+        } else {
+            $_statement = $_attr['start'];
+            $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
+            if (isset($_attr['step'])) {
+                $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = $_attr[step];";
+            } else {
+                $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = 1;";
+            }
+            if (isset($_attr['max'])) {
+                $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)min(ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step)),$_attr[max]);\n";
+            } else {
+                $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step));\n";
+            }
+            $output .= "if (\$_smarty_tpl->tpl_vars[$_statement[var]]->total > 0){\n";
+            $output .= "for (\$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value], \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration = 1;\$_smarty_tpl->tpl_vars[$_statement[var]]->iteration <= \$_smarty_tpl->tpl_vars[$_statement[var]]->total;\$_smarty_tpl->tpl_vars[$_statement[var]]->value += \$_smarty_tpl->tpl_vars[$_statement[var]]->step, \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration++){\n";
+            $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->first = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == 1;";
+            $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->last = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == \$_smarty_tpl->tpl_vars[$_statement[var]]->total;";
+        }
+        $output .= "?>";
+
+        $this->openTag($compiler, 'for', array('for', $compiler->nocache));
+        // maybe nocache because of nocache variables
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+        // return compiled code
+        return $output;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Forelse Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {forelse} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr  = $this->getAttributes($compiler, $args);
+
+        list($openTag, $nocache) = $this->closeTag($compiler, array('for'));
+        $this->openTag($compiler, 'forelse', array('forelse', $nocache));
+        return "<?php }} else { ?>";
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Forclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/for} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+
+        list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse'));
+
+        if ($openTag == 'forelse') {
+            return "<?php }  ?>";
+        } else {
+            return "<?php }} ?>";
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_foreach.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_foreach.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_foreach.php	(revision 345)
@@ -0,0 +1,231 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Foreach
+ *
+ * Compiles the {foreach} {foreachelse} {/foreach} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Foreach Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase {
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('from', 'item');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('name', 'key');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('from','item','key','name');
+
+    /**
+     * Compiles code for the {foreach} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        $tpl = $compiler->template;
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        $from = $_attr['from'];
+        $item = $_attr['item'];
+        if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) {
+            $compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno);
+        }
+
+        if (isset($_attr['key'])) {
+            $key = $_attr['key'];
+        } else {
+            $key = null;
+        }
+
+        $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key));
+        // maybe nocache because of nocache variables
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+        if (isset($_attr['name'])) {
+            $name = $_attr['name'];
+            $has_name = true;
+            $SmartyVarName = '$smarty.foreach.' . trim($name, '\'"') . '.';
+        } else {
+            $name = null;
+            $has_name = false;
+        }
+        $ItemVarName = '$' . trim($item, '\'"') . '@';
+        // evaluates which Smarty variables and properties have to be computed
+        if ($has_name) {
+            $usesSmartyFirst = strpos($tpl->source->content, $SmartyVarName . 'first') !== false;
+            $usesSmartyLast = strpos($tpl->source->content, $SmartyVarName . 'last') !== false;
+            $usesSmartyIndex = strpos($tpl->source->content, $SmartyVarName . 'index') !== false;
+            $usesSmartyIteration = strpos($tpl->source->content, $SmartyVarName . 'iteration') !== false;
+            $usesSmartyShow = strpos($tpl->source->content, $SmartyVarName . 'show') !== false;
+            $usesSmartyTotal = strpos($tpl->source->content, $SmartyVarName . 'total') !== false;
+        } else {
+            $usesSmartyFirst = false;
+            $usesSmartyLast = false;
+            $usesSmartyTotal = false;
+            $usesSmartyShow = false;
+        }
+
+        $usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false;
+        $usesPropLast = $usesSmartyLast || strpos($tpl->source->content, $ItemVarName . 'last') !== false;
+        $usesPropIndex = $usesPropFirst || strpos($tpl->source->content, $ItemVarName . 'index') !== false;
+        $usesPropIteration = $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'iteration') !== false;
+        $usesPropShow = strpos($tpl->source->content, $ItemVarName . 'show') !== false;
+        $usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'total') !== false;
+        // generate output code
+        $output = "<?php ";
+        $output .= " \$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable; \$_smarty_tpl->tpl_vars[$item]->_loop = false;\n";
+        if ($key != null) {
+            $output .= " \$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n";
+        }
+        $output .= " \$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}\n";
+        if ($usesPropTotal) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n";
+        }
+        if ($usesPropIteration) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration=0;\n";
+        }
+        if ($usesPropIndex) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->index=-1;\n";
+        }
+        if ($usesPropShow) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
+        }
+        if ($has_name) {
+            if ($usesSmartyTotal) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n";
+            }
+            if ($usesSmartyIteration) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n";
+            }
+            if ($usesSmartyIndex) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n";
+            }
+            if ($usesSmartyShow) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
+            }
+        }
+        $output .= "foreach (\$_from as \$_smarty_tpl->tpl_vars[$item]->key => \$_smarty_tpl->tpl_vars[$item]->value){\n\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n";
+        if ($key != null) {
+            $output .= " \$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n";
+        }
+        if ($usesPropIteration) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration++;\n";
+        }
+        if ($usesPropIndex) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->index++;\n";
+        }
+        if ($usesPropFirst) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index === 0;\n";
+        }
+        if ($usesPropLast) {
+            $output .= " \$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration === \$_smarty_tpl->tpl_vars[$item]->total;\n";
+        }
+        if ($has_name) {
+            if ($usesSmartyFirst) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['first'] = \$_smarty_tpl->tpl_vars[$item]->first;\n";
+            }
+            if ($usesSmartyIteration) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n";
+            }
+            if ($usesSmartyIndex) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n";
+            }
+            if ($usesSmartyLast) {
+                $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\n";
+            }
+        }
+        $output .= "?>";
+
+        return $output;
+    }
+}
+
+/**
+ * Smarty Internal Plugin Compile Foreachelse Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {foreachelse} tag
+     *
+     * @param array  $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        list($openTag, $nocache, $item, $key) = $this->closeTag($compiler, array('foreach'));
+        $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key));
+
+        return "<?php }\nif (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>";
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Foreachclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/foreach} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+
+        list($openTag, $compiler->nocache, $item, $key) = $this->closeTag($compiler, array('foreach', 'foreachelse'));
+
+        return "<?php } ?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_function.php	(revision 345)
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function
+ *
+ * Compiles the {function} {/function} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the {function} tag
+     *
+     * @param array $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array $parameter array with compilation parameter
+     * @return boolean true
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+        unset($_attr['nocache']);
+        $save = array($_attr, $compiler->parser->current_buffer,
+            $compiler->template->has_nocache_code, $compiler->template->required_plugins);
+        $this->openTag($compiler, 'function', $save);
+        $_name = trim($_attr['name'], "'\"");
+        unset($_attr['name']);
+        // set flag that we are compiling a template function
+        $compiler->compiles_template_function = true;
+        $compiler->template->properties['function'][$_name]['parameter'] = array();
+        $_smarty_tpl = $compiler->template;
+        foreach ($_attr as $_key => $_data) {
+            eval ('$tmp='.$_data.';');
+            $compiler->template->properties['function'][$_name]['parameter'][$_key] = $tmp;
+        }
+        $compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter'];
+        if ($compiler->template->caching) {
+            $output = '';
+        } else {
+            $output = "<?php if (!function_exists('smarty_template_function_{$_name}')) {
+    function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) {
+    \$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
+    foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
+    foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
+        }
+        // Init temporay context
+        $compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
+        $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
+        $compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
+        $compiler->template->has_nocache_code = false;
+        $compiler->has_code = false;
+        $compiler->template->properties['function'][$_name]['compiled'] = '';
+        return true;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Functionclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/function} tag
+     *
+     * @param array $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array $parameter array with compilation parameter
+     * @return boolean true
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        $saved_data = $this->closeTag($compiler, array('function'));
+        $_name = trim($saved_data[0]['name'], "'\"");
+        // build plugin include code
+        $plugins_string = '';
+        if (!empty($compiler->template->required_plugins['compiled'])) {
+            $plugins_string = '<?php ';
+            foreach($compiler->template->required_plugins['compiled'] as $tmp) {
+                foreach($tmp as $data) {
+                    $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
+                }
+            }
+            $plugins_string .= '?>';
+        }
+        if (!empty($compiler->template->required_plugins['nocache'])) {
+            $plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
+            foreach($compiler->template->required_plugins['nocache'] as $tmp) {
+                foreach($tmp as $data) {
+                    $plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
+                }
+            }
+            $plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n";
+        }
+         // remove last line break from function definition
+         $last = count($compiler->parser->current_buffer->subtrees) - 1;
+         if ($compiler->parser->current_buffer->subtrees[$last] instanceof _smarty_linebreak) {
+             unset($compiler->parser->current_buffer->subtrees[$last]);
+         }
+        // if caching save template function for possible nocache call
+        if ($compiler->template->caching) {
+            $compiler->template->properties['function'][$_name]['compiled'] .= $plugins_string
+             . $compiler->parser->current_buffer->to_smarty_php();
+            $compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
+            $compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
+            $compiler->template->properties['function'][$_name]['called_functions'] = $compiler->called_functions;
+            $compiler->called_functions = array();
+            $compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
+            $compiler->has_code = false;
+            $output = true;
+        } else {
+            $output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}}?>\n";
+        }
+        // reset flag that we are compiling a template function
+        $compiler->compiles_template_function = false;
+        // restore old compiler status
+        $compiler->parser->current_buffer = $saved_data[1];
+        $compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2];
+        $compiler->template->required_plugins = $saved_data[3];
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_if.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_if.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_if.php	(revision 345)
@@ -0,0 +1,207 @@
+<?php
+/**
+* Smarty Internal Plugin Compile If
+*
+* Compiles the {if} {else} {elseif} {/if} tags
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+/**
+* Smarty Internal Plugin Compile If Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase {
+
+    /**
+    * Compiles code for the {if} tag
+    *
+    * @param array  $args       array with attributes from parser
+    * @param object $compiler   compiler object
+    * @param array  $parameter  array with compilation parameter
+    * @return string compiled code
+    */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        $this->openTag($compiler, 'if', array(1, $compiler->nocache));
+        // must whole block be nocache ?
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+        if (!array_key_exists("if condition",$parameter)) {
+            $compiler->trigger_template_error("missing if condition", $compiler->lex->taglineno);
+        }
+
+        if (is_array($parameter['if condition'])) {
+            if ($compiler->nocache) {
+                $_nocache = ',true';
+                // create nocache var to make it know for further compiling
+                if (is_array($parameter['if condition']['var'])) {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
+                } else {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
+                }
+            } else {
+                $_nocache = '';
+            }
+            if (is_array($parameter['if condition']['var'])) {
+                $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]) || !is_array(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value)) \$_smarty_tpl->createLocalArrayVariable(".$parameter['if condition']['var']['var']."$_nocache);\n";
+                $_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value".$parameter['if condition']['var']['smarty_internal_index']." = ".$parameter['if condition']['value']."){?>";
+            } else {
+                $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."])) \$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."] = new Smarty_Variable(null{$_nocache});";
+                $_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."]->value = ".$parameter['if condition']['value']."){?>";
+            }
+            return $_output;
+        } else {
+            return "<?php if ({$parameter['if condition']}){?>";
+        }
+    }
+
+}
+
+/**
+* Smarty Internal Plugin Compile Else Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase {
+
+    /**
+    * Compiles code for the {else} tag
+    *
+    * @param array  $args       array with attributes from parser
+    * @param object $compiler   compiler object
+    * @param array  $parameter  array with compilation parameter
+    * @return string compiled code
+    */
+    public function compile($args, $compiler, $parameter)
+    {
+        list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
+        $this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache));
+
+        return "<?php }else{ ?>";
+    }
+
+}
+
+/**
+* Smarty Internal Plugin Compile ElseIf Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase {
+
+    /**
+    * Compiles code for the {elseif} tag
+    *
+    * @param array  $args       array with attributes from parser
+    * @param object $compiler   compiler object
+    * @param array  $parameter  array with compilation parameter
+    * @return string compiled code
+    */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
+
+        if (!array_key_exists("if condition",$parameter)) {
+            $compiler->trigger_template_error("missing elseif condition", $compiler->lex->taglineno);
+        }
+
+        if (is_array($parameter['if condition'])) {
+            $condition_by_assign = true;
+            if ($compiler->nocache) {
+                $_nocache = ',true';
+                // create nocache var to make it know for further compiling
+                if (is_array($parameter['if condition']['var'])) {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
+                } else {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
+                }
+            } else {
+                $_nocache = '';
+            }
+        } else {
+            $condition_by_assign = false;
+        }
+
+        if (empty($compiler->prefix_code)) {
+            if ($condition_by_assign) {
+                $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
+                if (is_array($parameter['if condition']['var'])) {
+                    $_output = "<?php }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+                    $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>";
+                } else {
+                    $_output = "<?php  }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+                    $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>";
+                }
+                return $_output;
+            } else {
+                $this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
+                return "<?php }elseif({$parameter['if condition']}){?>";
+            }
+        } else {
+            $tmp = '';
+            foreach ($compiler->prefix_code as $code)
+            $tmp .= $code;
+            $compiler->prefix_code = array();
+            $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
+            if ($condition_by_assign) {
+                if (is_array($parameter['if condition']['var'])) {
+                    $_output = "<?php }else{?>{$tmp}<?php  if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+                    $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>";
+                } else {
+                    $_output = "<?php }else{?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+                    $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>";
+                }
+                return $_output;
+            } else {
+                return "<?php }else{?>{$tmp}<?php if ({$parameter['if condition']}){?>";
+            }
+        }
+    }
+
+}
+
+/**
+* Smarty Internal Plugin Compile Ifclose Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase {
+
+    /**
+    * Compiles code for the {/if} tag
+    *
+    * @param array  $args       array with attributes from parser
+    * @param object $compiler   compiler object
+    * @param array  $parameter  array with compilation parameter
+    * @return string compiled code
+    */
+    public function compile($args, $compiler, $parameter)
+    {
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+        list($nesting, $compiler->nocache) = $this->closeTag($compiler, array('if', 'else', 'elseif'));
+        $tmp = '';
+        for ($i = 0; $i < $nesting; $i++) {
+            $tmp .= '}';
+        }
+        return "<?php {$tmp}?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include.php	(revision 345)
@@ -0,0 +1,215 @@
+<?php
+/**
+* Smarty Internal Plugin Compile Include
+*
+* Compiles the {include} tag
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+/**
+* Smarty Internal Plugin Compile Include Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
+
+    /**
+    * caching mode to create nocache code but no cache file
+    */
+    const CACHING_NOCACHE_CODE = 9999;
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $required_attributes = array('file');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $shorttag_order = array('file');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $option_flags = array('nocache', 'inline', 'caching');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $optional_attributes = array('_any');
+
+    /**
+    * Compiles code for the {include} tag
+    *
+     * @param array $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // save posible attributes
+        $include_file = $_attr['file'];
+
+        if (isset($_attr['assign'])) {
+            // output will be stored in a smarty variable instead of beind displayed
+            $_assign = $_attr['assign'];
+        }
+
+        $_parent_scope = Smarty::SCOPE_LOCAL;
+        if (isset($_attr['scope'])) {
+            $_attr['scope'] = trim($_attr['scope'], "'\"");
+            if ($_attr['scope'] == 'parent') {
+                $_parent_scope = Smarty::SCOPE_PARENT;
+            } elseif ($_attr['scope'] == 'root') {
+                $_parent_scope = Smarty::SCOPE_ROOT;
+            } elseif ($_attr['scope'] == 'global') {
+                $_parent_scope = Smarty::SCOPE_GLOBAL;
+            }
+        }
+        $_caching = 'null';
+        if ($compiler->nocache || $compiler->tag_nocache) {
+            $_caching = Smarty::CACHING_OFF;
+        }
+        // default for included templates
+        if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) {
+            $_caching = self::CACHING_NOCACHE_CODE;
+        }
+        /*
+        * if the {include} tag provides individual parameter for caching
+        * it will not be included into the common cache file and treated like
+        * a nocache section
+        */
+        if (isset($_attr['cache_lifetime'])) {
+            $_cache_lifetime = $_attr['cache_lifetime'];
+            $compiler->tag_nocache = true;
+            $_caching = Smarty::CACHING_LIFETIME_CURRENT;
+        } else {
+            $_cache_lifetime = 'null';
+        }
+        if (isset($_attr['cache_id'])) {
+            $_cache_id = $_attr['cache_id'];
+            $compiler->tag_nocache = true;
+            $_caching = Smarty::CACHING_LIFETIME_CURRENT;
+        } else {
+            $_cache_id = '$_smarty_tpl->cache_id';
+        }
+        if (isset($_attr['compile_id'])) {
+            $_compile_id = $_attr['compile_id'];
+        } else {
+            $_compile_id = '$_smarty_tpl->compile_id';
+        }
+        if ($_attr['caching'] === true) {
+            $_caching = Smarty::CACHING_LIFETIME_CURRENT;
+        }
+        if ($_attr['nocache'] === true) {
+            $compiler->tag_nocache = true;
+            $_caching = Smarty::CACHING_OFF;
+        }
+
+        $has_compiled_template = false;
+        if (($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled
+            && !($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache)) && $_caching != Smarty::CACHING_LIFETIME_CURRENT) {
+            // check if compiled code can be merged (contains no variable part)
+            if (!$compiler->has_variable_string && (substr_count($include_file, '"') == 2 or substr_count($include_file, "'") == 2)
+               and substr_count($include_file, '(') == 0 and substr_count($include_file, '$_smarty_tpl->') == 0) {
+                $tpl_name = null;
+                eval("\$tpl_name = $include_file;");
+                if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) {
+                    $tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
+                    // save unique function name
+                    $compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'.uniqid('', false);
+                    // use current nocache hash for inlined code
+                    $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
+                    if ($compiler->template->caching) {
+                        // needs code for cached page but no cache file
+                        $tpl->caching = self::CACHING_NOCACHE_CODE;
+                    }
+                    // make sure whole chain gest compiled
+                    $tpl->mustCompile = true;
+                    if (!($tpl->source->uncompiled) && $tpl->source->exists) {
+                        // get compiled code
+                        $compiled_code = $tpl->compiler->compileTemplate($tpl);
+                        // release compiler object to free memory
+                        unset($tpl->compiler);
+                        // merge compiled code for {function} tags
+                        $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
+                        // merge filedependency
+                        $tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp,$tpl->source->type);
+                        $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']);
+                        // remove header code
+                        $compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
+                        if ($tpl->has_nocache_code) {
+                            // replace nocache_hash
+                            $compiled_code = preg_replace("/{$tpl->properties['nocache_hash']}/", $compiler->template->properties['nocache_hash'], $compiled_code);
+                            $compiler->template->has_nocache_code = true;
+                        }
+                        $compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;
+                        $has_compiled_template = true;
+                    }
+                } else {
+                    $has_compiled_template = true;
+                }
+            }
+        }
+        // delete {include} standard attributes
+        unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
+        // remaining attributes must be assigned as smarty variable
+        if (!empty($_attr)) {
+            if ($_parent_scope == Smarty::SCOPE_LOCAL) {
+                // create variables
+                foreach ($_attr as $key => $value) {
+                    $_pairs[] = "'$key'=>$value";
+                }
+                $_vars = 'array('.join(',',$_pairs).')';
+                $_has_vars = true;
+            } else {
+                $compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
+            }
+        } else {
+            $_vars = 'array()';
+            $_has_vars = false;
+        }
+        if ($has_compiled_template) {
+            $_hash = $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'];
+            $_output = "<?php /*  Call merged included template \"" . $tpl_name . "\" */\n";
+            $_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
+            $_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
+            if (isset($_assign)) {
+                $_output .= 'ob_start(); ';
+            }
+            $_output .= $compiler->smarty->merged_templates_func[$tpl_name]['func']. "(\$_smarty_tpl);\n";
+            $_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
+            if (isset($_assign)) {
+                $_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
+            }
+            $_output .= "/*  End of included template \"" . $tpl_name . "\" */?>";
+            return $_output;
+        }
+
+        // was there an assign attribute
+        if (isset($_assign)) {
+            $_output = "<?php \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope));?>\n";;
+        } else {
+            $_output = "<?php echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope);?>\n";
+        }
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include_php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include_php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_include_php.php	(revision 345)
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Include PHP
+ *
+ * Compiles the {include_php} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('file');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('file');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('once', 'assign');
+
+    /**
+     * Compiles code for the {include_php} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        if (!($compiler->smarty instanceof SmartyBC)) {
+            throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable");
+        }
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        $_output = '<?php ';
+
+        $_smarty_tpl = $compiler->template;
+        $_filepath = false;
+        eval('$_file = ' . $_attr['file'] . ';');
+        if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
+            $_filepath = $_file;
+        } else {
+            if (isset($compiler->smarty->security_policy)) {
+                $_dir = $compiler->smarty->security_policy->trusted_dir;
+            } else {
+                $_dir = $compiler->smarty->trusted_dir;
+            }
+            if (!empty($_dir)) {
+                foreach((array)$_dir as $_script_dir) {
+                    $_script_dir = rtrim($_script_dir, '/\\') . DS;
+                    if (file_exists($_script_dir . $_file)) {
+                        $_filepath = $_script_dir .  $_file;
+                        break;
+                    }
+                }
+            }
+        }
+        if ($_filepath == false) {
+            $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", $compiler->lex->taglineno);
+        }
+
+        if (isset($compiler->smarty->security_policy)) {
+            $compiler->smarty->security_policy->isTrustedPHPDir($_filepath);
+        }
+
+        if (isset($_attr['assign'])) {
+            // output will be stored in a smarty variable instead of being displayed
+            $_assign = $_attr['assign'];
+        }
+        $_once = '_once';
+        if (isset($_attr['once'])) {
+            if ($_attr['once'] == 'false') {
+                $_once = '';
+            }
+        }
+
+        if (isset($_assign)) {
+            return "<?php ob_start(); include{$_once} ('{$_filepath}'); \$_smarty_tpl->assign({$_assign},ob_get_contents()); ob_end_clean();?>";
+        } else {
+            return "<?php include{$_once} ('{$_filepath}');?>\n";
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_insert.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_insert.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_insert.php	(revision 345)
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile Insert
+ *
+ * Compiles the {insert} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('name');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the {insert} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // never compile as nocache code
+        $compiler->suppressNocacheProcessing = true;
+        $compiler->tag_nocache = true;
+        $_smarty_tpl = $compiler->template;
+        $_name = null;
+        $_script = null;
+
+        $_output = '<?php ';
+        // save posible attributes
+        eval('$_name = ' . $_attr['name'] . ';');
+        if (isset($_attr['assign'])) {
+            // output will be stored in a smarty variable instead of being displayed
+            $_assign = $_attr['assign'];
+            // create variable to make shure that the compiler knows about its nocache status
+            $compiler->template->tpl_vars[trim($_attr['assign'], "'")] = new Smarty_Variable(null, true);
+        }
+        if (isset($_attr['script'])) {
+            // script which must be included
+            $_function = "smarty_insert_{$_name}";
+            $_smarty_tpl = $compiler->template;
+            $_filepath = false;
+            eval('$_script = ' . $_attr['script'] . ';');
+            if (!isset($compiler->smarty->security_policy) && file_exists($_script)) {
+                $_filepath = $_script;
+            } else {
+                if (isset($compiler->smarty->security_policy)) {
+                    $_dir = $compiler->smarty->security_policy->trusted_dir;
+                } else {
+                    $_dir = $compiler->smarty->trusted_dir;
+                }
+                if (!empty($_dir)) {
+                    foreach((array)$_dir as $_script_dir) {
+                        $_script_dir = rtrim($_script_dir, '/\\') . DS;
+                        if (file_exists($_script_dir . $_script)) {
+                            $_filepath = $_script_dir . $_script;
+                            break;
+                        }
+                    }
+                }
+            }
+            if ($_filepath == false) {
+                $compiler->trigger_template_error("{insert} missing script file '{$_script}'", $compiler->lex->taglineno);
+            }
+            // code for script file loading
+            $_output .= "require_once '{$_filepath}' ;";
+            require_once $_filepath;
+            if (!is_callable($_function)) {
+                $compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", $compiler->lex->taglineno);
+            }
+        } else {
+            $_filepath = 'null';
+            $_function = "insert_{$_name}";
+            // function in PHP script ?
+            if (!is_callable($_function)) {
+                // try plugin
+                if (!$_function = $compiler->getPlugin($_name, 'insert')) {
+                    $compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", $compiler->lex->taglineno);
+                }
+            }
+        }
+        // delete {insert} standard attributes
+        unset($_attr['name'], $_attr['assign'], $_attr['script'], $_attr['nocache']);
+        // convert attributes into parameter array string
+        $_paramsArray = array();
+        foreach ($_attr as $_key => $_value) {
+            $_paramsArray[] = "'$_key' => $_value";
+        }
+        $_params = 'array(' . implode(", ", $_paramsArray) . ')';
+        // call insert
+        if (isset($_assign)) {
+            if ($_smarty_tpl->caching) {
+                $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}',{$_assign});?>";
+            } else {
+                $_output .= "\$_smarty_tpl->assign({$_assign} , {$_function} ({$_params},\$_smarty_tpl), true);?>";
+            }
+        } else {
+            $compiler->has_output = true;
+            if ($_smarty_tpl->caching) {
+                $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}');?>";
+            } else {
+                $_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>";
+            }
+        }
+        return $_output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_ldelim.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_ldelim.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_ldelim.php	(revision 345)
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Ldelim
+ *
+ * Compiles the {ldelim} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Ldelim Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Ldelim extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {ldelim} tag
+     *
+     * This tag does output the left delimiter
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+        // this tag does not return compiled code
+        $compiler->has_code = true;
+        return $compiler->smarty->left_delimiter;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_nocache.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_nocache.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_nocache.php	(revision 345)
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Nocache
+ *
+ * Compiles the {nocache} {/nocache} tags.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Nocache Classv
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {nocache} tag
+     *
+     * This tag does not generate compiled output. It only sets a compiler flag.
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return bool
+     */
+    public function compile($args, $compiler)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+        // enter nocache mode
+        $compiler->nocache = true;
+        // this tag does not return compiled code
+        $compiler->has_code = false;
+        return true;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Nocacheclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/nocache} tag
+     *
+     * This tag does not generate compiled output. It only sets a compiler flag.
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return bool
+     */
+    public function compile($args, $compiler)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        // leave nocache mode
+        $compiler->nocache = false;
+        // this tag does not return compiled code
+        $compiler->has_code = false;
+        return true;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_block_plugin.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_block_plugin.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_block_plugin.php	(revision 345)
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Block Plugin
+ *
+ * Compiles code for the execution of block plugin
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Block Plugin Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of block plugin
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @param string $tag       name of block plugin
+     * @param string $function  PHP function name
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag, $function)
+    {
+        if (!isset($tag[5]) || substr($tag, -5) != 'close') {
+            // opening tag of block plugin
+            // check and get attributes
+            $_attr = $this->getAttributes($compiler, $args);
+            if ($_attr['nocache'] === true) {
+                $compiler->tag_nocache = true;
+            }
+               unset($_attr['nocache']);
+            // convert attributes into parameter array string
+            $_paramsArray = array();
+            foreach ($_attr as $_key => $_value) {
+                if (is_int($_key)) {
+                    $_paramsArray[] = "$_key=>$_value";
+                } else {
+                    $_paramsArray[] = "'$_key'=>$_value";
+                }
+            }
+            $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+            $this->openTag($compiler, $tag, array($_params, $compiler->nocache));
+            // maybe nocache because of nocache variables or nocache plugin
+            $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+            // compile code
+            $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+        } else {
+            // must endblock be nocache?
+            if ($compiler->nocache) {
+                $compiler->tag_nocache = true;
+            }
+            // closing tag of block plugin, restore nocache
+            list($_params, $compiler->nocache) = $this->closeTag($compiler, substr($tag, 0, -5));
+            // This tag does create output
+            $compiler->has_output = true;
+            // compile code
+            if (!isset($parameter['modifier_list'])) {
+                $mod_pre = $mod_post ='';
+            } else {
+                $mod_pre = ' ob_start(); ';
+                $mod_post = 'echo '.$compiler->compileTag('private_modifier',array(),array('modifierlist'=>$parameter['modifier_list'],'value'=>'ob_get_clean()')).';';
+            }
+            $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post." } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+        }
+        return $output . "\n";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_function_plugin.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_function_plugin.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_function_plugin.php	(revision 345)
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function Plugin
+ *
+ * Compiles code for the execution of function plugin
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function Plugin Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array();
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of function plugin
+     *
+     * @param array $args array with attributes from parser
+     * @param object $compiler compiler object
+     * @param array $parameter array with compilation parameter
+     * @param string $tag name of function plugin
+     * @param string $function PHP function name
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag, $function)
+    {
+        // This tag does create output
+        $compiler->has_output = true;
+
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->tag_nocache = true;
+        }
+        unset($_attr['nocache']);
+        // convert attributes into parameter array string
+        $_paramsArray = array();
+        foreach ($_attr as $_key => $_value) {
+            if (is_int($_key)) {
+                $_paramsArray[] = "$_key=>$_value";
+            } else {
+                $_paramsArray[] = "'$_key'=>$_value";
+            }
+        }
+        $_params = 'array(' . implode(",", $_paramsArray) . ')';
+        // compile code
+        $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_modifier.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_modifier.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_modifier.php	(revision 345)
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile Modifier
+ *
+ * Compiles code for modifier execution
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Modifier Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for modifier execution
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        $output = $parameter['value'];
+        // loop over list of modifiers
+        foreach ($parameter['modifierlist'] as $single_modifier) {
+            $modifier = $single_modifier[0];
+            $single_modifier[0] = $output;
+            $params = implode(',', $single_modifier);
+            // check for registered modifier
+            if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) {
+                $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
+                if (!is_array($function)) {
+                    $output = "{$function}({$params})";
+                } else {
+                    if (is_object($function[0])) {
+                        $output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
+                    } else {
+                        $output = $function[0] . '::' . $function[1] . '(' . $params . ')';
+                    }
+                }
+            } else if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
+                $output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
+                // check for plugin modifiercompiler
+            } else if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
+                // check if modifier allowed
+                if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+                    $plugin = 'smarty_modifiercompiler_' . $modifier;
+                    $output = $plugin($single_modifier, $compiler);
+                }
+                // check for plugin modifier
+            } else if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
+                // check if modifier allowed
+                if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+                    $output = "{$function}({$params})";
+                }
+                // check if trusted PHP function
+            } else if (is_callable($modifier)) {
+                // check if modifier allowed
+                if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
+                    $output = "{$modifier}({$params})";
+                }
+            } else {
+                $compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
+            }
+        }
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_block_function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_block_function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_block_function.php	(revision 345)
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Object Block Function
+ *
+ * Compiles code for registered objects as block function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Object Block Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of block plugin
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @param string $tag       name of block object
+     * @param string $method    name of method to call
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag, $method)
+    {
+        if (!isset($tag[5]) || substr($tag, -5) != 'close') {
+            // opening tag of block plugin
+            // check and get attributes
+            $_attr = $this->getAttributes($compiler, $args);
+            if ($_attr['nocache'] === true) {
+                $compiler->tag_nocache = true;
+            }
+            unset($_attr['nocache']);
+            // convert attributes into parameter array string
+            $_paramsArray = array();
+            foreach ($_attr as $_key => $_value) {
+                if (is_int($_key)) {
+                    $_paramsArray[] = "$_key=>$_value";
+                } else {
+                    $_paramsArray[] = "'$_key'=>$_value";
+                }
+            }
+            $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+            $this->openTag($compiler, $tag . '->' . $method, array($_params, $compiler->nocache));
+            // maybe nocache because of nocache variables or nocache plugin
+            $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+            // compile code
+            $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+        } else {
+            $base_tag = substr($tag, 0, -5);
+            // must endblock be nocache?
+            if ($compiler->nocache) {
+                $compiler->tag_nocache = true;
+            }
+            // closing tag of block plugin, restore nocache
+            list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag . '->' . $method);
+            // This tag does create output
+            $compiler->has_output = true;
+            // compile code
+            if (!isset($parameter['modifier_list'])) {
+                $mod_pre = $mod_post = '';
+            } else {
+                $mod_pre = ' ob_start(); ';
+                $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
+            }
+            $output = "<?php \$_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "  } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+        }
+        return $output . "\n";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_object_function.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Object Funtion
+ *
+ * Compiles code for registered objects as function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Object Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of function plugin
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @param string $tag       name of function
+     * @param string $method    name of method to call
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag, $method)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->tag_nocache = true;
+        }
+        unset($_attr['nocache']);
+        $_assign = null;
+        if (isset($_attr['assign'])) {
+            $_assign = $_attr['assign'];
+            unset($_attr['assign']);
+        }
+        // convert attributes into parameter array string
+        if ($compiler->smarty->registered_objects[$tag][2]) {
+            $_paramsArray = array();
+            foreach ($_attr as $_key => $_value) {
+                if (is_int($_key)) {
+                    $_paramsArray[] = "$_key=>$_value";
+                } else {
+                    $_paramsArray[] = "'$_key'=>$_value";
+                }
+            }
+            $_params = 'array(' . implode(",", $_paramsArray) . ')';
+            $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params},\$_smarty_tpl)";
+        } else {
+            $_params = implode(",", $_attr);
+            $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params})";
+        }
+        if (empty($_assign)) {
+            // This tag does create output
+            $compiler->has_output = true;
+            $output = "<?php echo {$return};?>\n";
+        } else {
+            $output = "<?php \$_smarty_tpl->assign({$_assign},{$return});?>\n";
+        }
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_print_expression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_print_expression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_print_expression.php	(revision 345)
@@ -0,0 +1,156 @@
+<?php
+/**
+* Smarty Internal Plugin Compile Print Expression
+*
+* Compiles any tag which will output an expression or variable
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+/**
+* Smarty Internal Plugin Compile Print Expression Class
+*
+* @package Smarty
+* @subpackage Compiler
+*/
+class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase {
+
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $optional_attributes = array('assign');
+    /**
+    * Attribute definition: Overwrites base class.
+    *
+    * @var array
+    * @see Smarty_Internal_CompileBase
+    */
+    public $option_flags = array('nocache', 'nofilter');
+
+    /**
+    * Compiles code for gererting output from any expression
+    *
+    * @param array  $args      array with attributes from parser
+    * @param object $compiler  compiler object
+    * @param array  $parameter array with compilation parameter
+    * @return string compiled code
+    */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        // nocache option
+        if ($_attr['nocache'] === true) {
+            $compiler->tag_nocache = true;
+        }
+        // filter handling
+        if ($_attr['nofilter'] === true) {
+            $_filter = 'false';
+        } else {
+            $_filter = 'true';
+        }
+        if (isset($_attr['assign'])) {
+            // assign output to variable
+            $output = "<?php \$_smarty_tpl->assign({$_attr['assign']},{$parameter['value']});?>";
+        } else {
+            // display value
+            $output = $parameter['value'];
+            // tag modifier
+            if (!empty($parameter['modifierlist'])) {
+                $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'], 'value' => $output));
+            }
+            if (!$_attr['nofilter']) {
+                // default modifier
+                if (!empty($compiler->smarty->default_modifiers)) {
+                    if (empty($compiler->default_modifier_list)) {
+                        $modifierlist = array();
+                        foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) {
+                            preg_match_all('/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', $single_default_modifier, $mod_array);
+                            for ($i = 0, $count = count($mod_array[0]);$i < $count;$i++) {
+                                if ($mod_array[0][$i] != ':') {
+                                    $modifierlist[$key][] = $mod_array[0][$i];
+                                }
+                            }
+                        }
+                        $compiler->default_modifier_list  = $modifierlist;
+                    }
+                    $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list, 'value' => $output));
+                }
+                // autoescape html
+                if ($compiler->template->smarty->escape_html) {
+                    $output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
+                }
+                // loop over registerd filters
+                if (!empty($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE])) {
+                    foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key => $function) {
+                        if (!is_array($function)) {
+                            $output = "{$function}({$output},\$_smarty_tpl)";
+                        } else if (is_object($function[0])) {
+                            $output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE][{$key}][0]->{$function[1]}({$output},\$_smarty_tpl)";
+                        } else {
+                            $output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)";
+                        }
+                    }
+                }
+                // auto loaded filters
+                if (isset($compiler->smarty->autoload_filters[Smarty::FILTER_VARIABLE])) {
+                    foreach ((array)$compiler->template->smarty->autoload_filters[Smarty::FILTER_VARIABLE] as $name) {
+                        $result = $this->compile_output_filter($compiler, $name, $output);
+                        if ($result !== false) {
+                            $output = $result;
+                        } else {
+                            // not found, throw exception
+                            throw new SmartyException("Unable to load filter '{$name}'");
+                        }
+                    }
+                }
+                if (isset($compiler->template->variable_filters)) {
+                    foreach ($compiler->template->variable_filters as $filter) {
+                        if (count($filter) == 1 && ($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false) {
+                            $output = $result;
+                        } else {
+                            $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter), 'value' => $output));
+                        }
+                    }
+                }
+            }
+
+            $compiler->has_output = true;
+            $output = "<?php echo {$output};?>";
+        }
+        return $output;
+    }
+
+    /**
+    * @param object $compiler compiler object
+    * @param string $name     name of variable filter
+    * @param type   $output   embedded output
+    * @return string
+    */
+    private function compile_output_filter($compiler, $name, $output)
+    {
+        $plugin_name = "smarty_variablefilter_{$name}";
+        $path = $compiler->smarty->loadPlugin($plugin_name, false);
+        if ($path) {
+            if ($compiler->template->caching) {
+                $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
+                $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
+            } else {
+                $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
+                $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
+            }
+        } else {
+            // not found
+            return false;
+        }
+        return "{$plugin_name}({$output},\$_smarty_tpl)";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_block.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_block.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_block.php	(revision 345)
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Registered Block
+ *
+ * Compiles code for the execution of a registered block function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Block Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of a block function
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @param string $tag       name of block function
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag)
+    {
+        if (!isset($tag[5]) || substr($tag,-5) != 'close') {
+            // opening tag of block plugin
+            // check and get attributes
+            $_attr = $this->getAttributes($compiler, $args);
+            if ($_attr['nocache']) {
+                $compiler->tag_nocache = true;
+            }
+               unset($_attr['nocache']);
+               if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
+                   $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
+               } else {
+                   $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
+               }
+            // convert attributes into parameter array string
+            $_paramsArray = array();
+            foreach ($_attr as $_key => $_value) {
+                if (is_int($_key)) {
+                    $_paramsArray[] = "$_key=>$_value";
+                } elseif ($compiler->template->caching && in_array($_key,$tag_info[2])) {
+                    $_value = str_replace("'","^#^",$_value);
+                    $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+                } else {
+                    $_paramsArray[] = "'$_key'=>$_value";
+                }
+            }
+            $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+            $this->openTag($compiler, $tag, array($_params, $compiler->nocache));
+            // maybe nocache because of nocache variables or nocache plugin
+            $compiler->nocache = !$tag_info[1] | $compiler->nocache | $compiler->tag_nocache;
+            $function = $tag_info[0];
+            // compile code
+            if (!is_array($function)) {
+                $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+            } else if (is_object($function[0])) {
+                $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+            } else {
+                $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+            }
+        } else {
+            // must endblock be nocache?
+            if ($compiler->nocache) {
+                $compiler->tag_nocache = true;
+            }
+            $base_tag = substr($tag, 0, -5);
+            // closing tag of block plugin, restore nocache
+            list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag);
+            // This tag does create output
+            $compiler->has_output = true;
+               if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+                   $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+               } else {
+                   $function = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+               }
+            // compile code
+            if (!isset($parameter['modifier_list'])) {
+                $mod_pre = $mod_post ='';
+            } else {
+                $mod_pre = ' ob_start(); ';
+                $mod_post = 'echo '.$compiler->compileTag('private_modifier',array(),array('modifierlist'=>$parameter['modifier_list'],'value'=>'ob_get_clean()')).';';
+            }
+            if (!is_array($function)) {
+                $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);".$mod_post." } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+            } else if (is_object($function[0])) {
+                $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post."} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+            } else {
+                $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post."} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+            }
+        }
+        return $output . "\n";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_registered_function.php	(revision 345)
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Registered Function
+ *
+ * Compiles code for the execution of a registered function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Function extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('_any');
+
+    /**
+     * Compiles code for the execution of a registered function
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @param string $tag       name of function
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter, $tag)
+    {
+        // This tag does create output
+        $compiler->has_output = true;
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache']) {
+            $compiler->tag_nocache = true;
+        }
+        unset($_attr['nocache']);
+               if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag])) {
+                   $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+               } else {
+                   $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+               }
+        // not cachable?
+        $compiler->tag_nocache =  $compiler->tag_nocache || !$tag_info[1];
+        // convert attributes into parameter array string
+        $_paramsArray = array();
+        foreach ($_attr as $_key => $_value) {
+            if (is_int($_key)) {
+                $_paramsArray[] = "$_key=>$_value";
+            } elseif ($compiler->template->caching && in_array($_key,$tag_info[2])) {
+                $_value = str_replace("'","^#^",$_value);
+                $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+            } else {
+                $_paramsArray[] = "'$_key'=>$_value";
+            }
+        }
+        $_params = 'array(' . implode(",", $_paramsArray) . ')';
+        $function = $tag_info[0];
+        // compile code
+        if (!is_array($function)) {
+            $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
+        } else if (is_object($function[0])) {
+            $output = "<?php echo \$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0][0]->{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+        } else {
+            $output = "<?php echo {$function[0]}::{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+        }
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_special_variable.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_special_variable.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_private_special_variable.php	(revision 345)
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Special Smarty Variable
+ *
+ * Compiles the special $smarty variables
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile special Smarty Variable Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the speical $smarty variables
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        $_index = preg_split("/\]\[/",substr($parameter, 1, strlen($parameter)-2));
+        $compiled_ref = ' ';
+        $variable = trim($_index[0], "'");
+        switch ($variable) {
+            case 'foreach':
+                return "\$_smarty_tpl->getVariable('smarty')->value$parameter";
+            case 'section':
+                return "\$_smarty_tpl->getVariable('smarty')->value$parameter";
+            case 'capture':
+                return "Smarty::\$_smarty_vars$parameter";
+            case 'now':
+                return 'time()';
+            case 'cookies':
+                if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
+                    $compiler->trigger_template_error("(secure mode) super globals not permitted");
+                    break;
+                }
+                $compiled_ref = '$_COOKIE';
+                break;
+
+            case 'get':
+            case 'post':
+            case 'env':
+            case 'server':
+            case 'session':
+            case 'request':
+                if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
+                    $compiler->trigger_template_error("(secure mode) super globals not permitted");
+                    break;
+                }
+                $compiled_ref = '$_'.strtoupper($variable);
+                break;
+
+            case 'template':
+                return 'basename($_smarty_tpl->source->filepath)';
+
+            case 'current_dir':
+                return 'dirname($_smarty_tpl->source->filepath)';
+
+            case 'version':
+                $_version = Smarty::SMARTY_VERSION;
+                return "'$_version'";
+
+            case 'const':
+                if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_constants) {
+                    $compiler->trigger_template_error("(secure mode) constants not permitted");
+                    break;
+                }
+                return '@' . trim($_index[1], "'");
+
+            case 'config':
+                return "\$_smarty_tpl->getConfigVariable($_index[1])";
+            case 'ldelim':
+                $_ldelim = $compiler->smarty->left_delimiter;
+                return "'$_ldelim'";
+
+            case 'rdelim':
+                $_rdelim = $compiler->smarty->right_delimiter;
+                return "'$_rdelim'";
+
+            default:
+                $compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
+                break;
+        }
+        if (isset($_index[1])) {
+            array_shift($_index);
+            foreach ($_index as $_ind) {
+                $compiled_ref = $compiled_ref . "[$_ind]";
+            }
+        }
+        return $compiled_ref;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_rdelim.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_rdelim.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_rdelim.php	(revision 345)
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Rdelim
+ *
+ * Compiles the {rdelim} tag
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Rdelim Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Rdelim extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {rdelim} tag
+     *
+     * This tag does output the right delimiter.
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        if ($_attr['nocache'] === true) {
+            $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+        }
+        // this tag does not return compiled code
+        $compiler->has_code = true;
+        return $compiler->smarty->right_delimiter;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_section.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_section.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_section.php	(revision 345)
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Section
+ *
+ * Compiles the {section} {sectionelse} {/section} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Section Class
+ * 
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase {
+
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $required_attributes = array('name', 'loop');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $shorttag_order = array('name', 'loop');
+    /**
+     * Attribute definition: Overwrites base class.
+     *
+     * @var array
+     * @see Smarty_Internal_CompileBase
+     */
+    public $optional_attributes = array('start', 'step', 'max', 'show');
+
+    /**
+     * Compiles code for the {section} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        $this->openTag($compiler, 'section', array('section', $compiler->nocache));
+        // maybe nocache because of nocache variables
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+        $output = "<?php ";
+
+        $section_name = $_attr['name'];
+
+        $output .= "if (isset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name])) unset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]);\n";
+        $section_props = "\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]";
+
+        foreach ($_attr as $attr_name => $attr_value) {
+            switch ($attr_name) {
+                case 'loop':
+                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+                    break;
+
+                case 'show':
+                    if (is_bool($attr_value))
+                        $show_attr_value = $attr_value ? 'true' : 'false';
+                    else
+                        $show_attr_value = "(bool)$attr_value";
+                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
+                    break;
+
+                case 'name':
+                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+                    break;
+
+                case 'max':
+                case 'start':
+                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+                    break;
+
+                case 'step':
+                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+                    break;
+            }
+        }
+
+        if (!isset($_attr['show']))
+            $output .= "{$section_props}['show'] = true;\n";
+
+        if (!isset($_attr['loop']))
+            $output .= "{$section_props}['loop'] = 1;\n";
+
+        if (!isset($_attr['max']))
+            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+        else
+            $output .= "if ({$section_props}['max'] < 0)\n" . "    {$section_props}['max'] = {$section_props}['loop'];\n";
+
+        if (!isset($_attr['step']))
+            $output .= "{$section_props}['step'] = 1;\n";
+
+        if (!isset($_attr['start']))
+            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+        else {
+            $output .= "if ({$section_props}['start'] < 0)\n" . "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . "else\n" . "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+        }
+
+        $output .= "if ({$section_props}['show']) {\n";
+        if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) {
+            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
+        } else {
+            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+        }
+        $output .= "    if ({$section_props}['total'] == 0)\n" . "        {$section_props}['show'] = false;\n" . "} else\n" . "    {$section_props}['total'] = 0;\n";
+
+        $output .= "if ({$section_props}['show']):\n";
+        $output .= "
+            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+                 {$section_props}['iteration'] <= {$section_props}['total'];
+                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
+        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+        $output .= "?>";
+        return $output;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Sectionelse Class
+ * 
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {sectionelse} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        list($openTag, $nocache) = $this->closeTag($compiler, array('section'));
+        $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache));
+
+        return "<?php endfor; else: ?>";
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Sectionclose Class
+ * 
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/section} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+
+        list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('section', 'sectionelse'));
+
+        if ($openTag == 'sectionelse') {
+            return "<?php endif; ?>";
+        } else {
+            return "<?php endfor; endif; ?>";
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_setfilter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_setfilter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_setfilter.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Setfilter
+ *
+ * Compiles code for setfilter tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Setfilter Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilter extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for setfilter tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        $compiler->variable_filter_stack[] = $compiler->template->variable_filters;
+        $compiler->template->variable_filters = $parameter['modifier_list'];
+        // this tag does not return compiled code
+        $compiler->has_code = false;
+        return true;
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Setfilterclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilterclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/setfilter} tag
+     *
+     * This tag does not generate compiled output. It resets variable filter.
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        $_attr = $this->getAttributes($compiler, $args);
+        // reset variable filter to previous state
+        if (count($compiler->variable_filter_stack)) {
+            $compiler->template->variable_filters = array_pop($compiler->variable_filter_stack);
+        } else {
+            $compiler->template->variable_filters = array();
+        }
+        // this tag does not return compiled code
+        $compiler->has_code = false;
+        return true;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_while.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_while.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compile_while.php	(revision 345)
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile While
+ *
+ * Compiles the {while} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile While Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {while} tag
+     *
+     * @param array  $args      array with attributes from parser
+     * @param object $compiler  compiler object
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compile($args, $compiler, $parameter)
+    {
+        // check and get attributes
+        $_attr = $this->getAttributes($compiler, $args);
+        $this->openTag($compiler, 'while', $compiler->nocache);
+
+        if (!array_key_exists("if condition",$parameter)) {
+            $compiler->trigger_template_error("missing while condition", $compiler->lex->taglineno);
+        }
+
+        // maybe nocache because of nocache variables
+        $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+        if (is_array($parameter['if condition'])) {
+            if ($compiler->nocache) {
+                $_nocache = ',true';
+                // create nocache var to make it know for further compiling
+                if (is_array($parameter['if condition']['var'])) {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
+                } else {
+                    $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
+                }
+            } else {
+                $_nocache = '';
+            }
+            if (is_array($parameter['if condition']['var'])) {
+                $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+                $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>";
+            } else {
+                $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+                $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>";
+            }
+            return $_output;
+        } else {
+            return "<?php while ({$parameter['if condition']}){?>";
+        }
+    }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Whileclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Whileclose extends Smarty_Internal_CompileBase {
+
+    /**
+     * Compiles code for the {/while} tag
+     *
+     * @param array  $args     array with attributes from parser
+     * @param object $compiler compiler object
+     * @return string compiled code
+     */
+    public function compile($args, $compiler)
+    {
+        // must endblock be nocache?
+        if ($compiler->nocache) {
+            $compiler->tag_nocache = true;
+        }
+        $compiler->nocache = $this->closeTag($compiler, array('while'));
+        return "<?php }?>";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compilebase.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compilebase.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_compilebase.php	(revision 345)
@@ -0,0 +1,176 @@
+<?php
+/**
+ * Smarty Internal Plugin CompileBase
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * This class does extend all internal compile plugins
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+abstract class Smarty_Internal_CompileBase {
+
+    /**
+     * Array of names of required attribute required by tag
+     *
+     * @var array
+     */
+    public $required_attributes = array();
+    /**
+     * Array of names of optional attribute required by tag
+     * use array('_any') if there is no restriction of attributes names
+     *
+     * @var array
+     */
+    public $optional_attributes = array();
+    /**
+     * Shorttag attribute order defined by its names
+     *
+     * @var array
+     */
+    public $shorttag_order = array();
+    /**
+     * Array of names of valid option flags
+     *
+     * @var array
+     */
+    public $option_flags = array('nocache');
+
+    /**
+     * This function checks if the attributes passed are valid
+     *
+     * The attributes passed for the tag to compile are checked against the list of required and
+     * optional attributes. Required attributes must be present. Optional attributes are check against
+     * the corresponding list. The keyword '_any' specifies that any attribute will be accepted
+     * as valid
+     *
+     * @param object $compiler   compiler object
+     * @param array  $attributes attributes applied to the tag
+     * @return array of mapped attributes for further processing
+     */
+    public function getAttributes($compiler, $attributes)
+    {
+        $_indexed_attr = array();
+        // loop over attributes
+        foreach ($attributes as $key => $mixed) {
+            // shorthand ?
+            if (!is_array($mixed)) {
+                // option flag ?
+                if (in_array(trim($mixed, '\'"'), $this->option_flags)) {
+                    $_indexed_attr[trim($mixed, '\'"')] = true;
+                    // shorthand attribute ?
+                } else if (isset($this->shorttag_order[$key])) {
+                    $_indexed_attr[$this->shorttag_order[$key]] = $mixed;
+                } else {
+                    // too many shorthands
+                    $compiler->trigger_template_error('too many shorthand attributes', $compiler->lex->taglineno);
+                }
+                // named attribute
+            } else {
+                $kv = each($mixed);
+                // option flag?
+                if (in_array($kv['key'], $this->option_flags)) {
+                    if (is_bool($kv['value'])) {
+                        $_indexed_attr[$kv['key']] = $kv['value'];
+                    } else if (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) {
+                        if (trim($kv['value']) == 'true') {
+                            $_indexed_attr[$kv['key']] = true;
+                        } else {
+                            $_indexed_attr[$kv['key']] = false;
+                        }
+                    } else if (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) {
+                        if ($kv['value'] == 1) {
+                            $_indexed_attr[$kv['key']] = true;
+                        } else {
+                            $_indexed_attr[$kv['key']] = false;
+                        }
+                    } else {
+                        $compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $compiler->lex->taglineno);
+                    }
+                    // must be named attribute
+                } else {
+                    reset($mixed);
+                    $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
+                }
+            }
+        }
+        // check if all required attributes present
+        foreach ($this->required_attributes as $attr) {
+            if (!array_key_exists($attr, $_indexed_attr)) {
+                $compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $compiler->lex->taglineno);
+            }
+        }
+        // check for unallowed attributes
+        if ($this->optional_attributes != array('_any')) {
+            $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
+            foreach ($_indexed_attr as $key => $dummy) {
+                if (!in_array($key, $tmp_array) && $key !== 0) {
+                    $compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $compiler->lex->taglineno);
+                }
+            }
+        }
+        // default 'false' for all option flags not set
+        foreach ($this->option_flags as $flag) {
+            if (!isset($_indexed_attr[$flag])) {
+                $_indexed_attr[$flag] = false;
+            }
+        }
+
+        return $_indexed_attr;
+    }
+
+    /**
+     * Push opening tag name on stack
+     *
+     * Optionally additional data can be saved on stack
+     *
+     * @param object    $compiler   compiler object
+     * @param string    $openTag    the opening tag's name
+     * @param mixed     $data       optional data saved
+     */
+    public function openTag($compiler, $openTag, $data = null)
+    {
+        array_push($compiler->_tag_stack, array($openTag, $data));
+    }
+
+    /**
+     * Pop closing tag
+     *
+     * Raise an error if this stack-top doesn't match with expected opening tags
+     *
+     * @param object       $compiler    compiler object
+     * @param array|string $expectedTag the expected opening tag names
+     * @return mixed any type the opening tag's name or saved data
+     */
+    public function closeTag($compiler, $expectedTag)
+    {
+        if (count($compiler->_tag_stack) > 0) {
+            // get stacked info
+            list($_openTag, $_data) = array_pop($compiler->_tag_stack);
+            // open tag must match with the expected ones
+            if (in_array($_openTag, (array) $expectedTag)) {
+                if (is_null($_data)) {
+                    // return opening tag
+                    return $_openTag;
+                } else {
+                    // return restored data
+                    return $_data;
+                }
+            }
+            // wrong nesting of tags
+            $compiler->trigger_template_error("unclosed {" . $_openTag . "} tag");
+            return;
+        }
+        // wrong nesting of tags
+        $compiler->trigger_template_error("unexpected closing tag", $compiler->lex->taglineno);
+        return;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config.php	(revision 345)
@@ -0,0 +1,303 @@
+<?php
+/**
+ * Smarty Internal Plugin Config
+ *
+ * @package Smarty
+ * @subpackage Config
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Config
+ *
+ * Main class for config variables
+ *
+ * @package Smarty
+ * @subpackage Config
+ *
+ * @property Smarty_Config_Source   $source
+ * @property Smarty_Config_Compiled $compiled
+ * @ignore
+ */
+class Smarty_Internal_Config {
+
+    /**
+     * Samrty instance
+     *
+     * @var Smarty object
+     */
+    public $smarty = null;
+    /**
+     * Object of config var storage
+     *
+     * @var object
+     */
+    public $data = null;
+    /**
+     * Config resource
+     * @var string
+     */
+    public $config_resource = null;
+    /**
+     * Compiled config file
+     *
+     * @var string
+     */
+    public $compiled_config = null;
+    /**
+     * filepath of compiled config file
+     *
+     * @var string
+     */
+    public $compiled_filepath = null;
+    /**
+     * Filemtime of compiled config Filemtime
+     *
+     * @var int
+     */
+    public $compiled_timestamp = null;
+    /**
+     * flag if compiled config file is invalid and must be (re)compiled
+     * @var bool
+     */
+    public $mustCompile = null;
+    /**
+     * Config file compiler object
+     *
+     * @var Smarty_Internal_Config_File_Compiler object
+     */
+    public $compiler_object = null;
+
+    /**
+     * Constructor of config file object
+     *
+     * @param string $config_resource config file resource name
+     * @param Smarty $smarty Smarty instance
+     * @param object $data object for config vars storage
+     */
+    public function __construct($config_resource, $smarty, $data = null)
+    {
+        $this->data = $data;
+        $this->smarty = $smarty;
+        $this->config_resource = $config_resource;
+    }
+
+    /**
+     * Returns the compiled  filepath
+     *
+     * @return string the compiled filepath
+     */
+    public function getCompiledFilepath()
+    {
+        return $this->compiled_filepath === null ?
+                ($this->compiled_filepath = $this->buildCompiledFilepath()) :
+                $this->compiled_filepath;
+    }
+
+    /**
+     * Get file path.
+     *
+     * @return string
+     */
+    public function buildCompiledFilepath()
+    {
+        $_compile_id = isset($this->smarty->compile_id) ? preg_replace('![^\w\|]+!', '_', $this->smarty->compile_id) : null;
+        $_flag = (int) $this->smarty->config_read_hidden + (int) $this->smarty->config_booleanize * 2
+                + (int) $this->smarty->config_overwrite * 4;
+        $_filepath = sha1($this->source->name . $_flag);
+        // if use_sub_dirs, break file into directories
+        if ($this->smarty->use_sub_dirs) {
+            $_filepath = substr($_filepath, 0, 2) . DS
+                    . substr($_filepath, 2, 2) . DS
+                    . substr($_filepath, 4, 2) . DS
+                    . $_filepath;
+        }
+        $_compile_dir_sep = $this->smarty->use_sub_dirs ? DS : '^';
+        if (isset($_compile_id)) {
+            $_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
+        }
+        $_compile_dir = $this->smarty->getCompileDir();
+        return $_compile_dir . $_filepath . '.' . basename($this->source->name) . '.config' . '.php';
+    }
+
+    /**
+     * Returns the timpestamp of the compiled file
+     *
+     * @return integer the file timestamp
+     */
+    public function getCompiledTimestamp()
+    {
+        return $this->compiled_timestamp === null
+            ? ($this->compiled_timestamp = (file_exists($this->getCompiledFilepath())) ? filemtime($this->getCompiledFilepath()) : false)
+            : $this->compiled_timestamp;
+    }
+
+    /**
+     * Returns if the current config file must be compiled
+     *
+     * It does compare the timestamps of config source and the compiled config and checks the force compile configuration
+     *
+     * @return boolean true if the file must be compiled
+     */
+    public function mustCompile()
+    {
+        return $this->mustCompile === null ?
+            $this->mustCompile = ($this->smarty->force_compile || $this->getCompiledTimestamp () === false || $this->smarty->compile_check && $this->getCompiledTimestamp () < $this->source->timestamp):
+            $this->mustCompile;
+    }
+
+    /**
+     * Returns the compiled config file
+     *
+     * It checks if the config file must be compiled or just read the compiled version
+     *
+     * @return string the compiled config file
+     */
+    public function getCompiledConfig()
+    {
+        if ($this->compiled_config === null) {
+            // see if template needs compiling.
+            if ($this->mustCompile()) {
+                $this->compileConfigSource();
+            } else {
+                $this->compiled_config = file_get_contents($this->getCompiledFilepath());
+            }
+        }
+        return $this->compiled_config;
+    }
+
+    /**
+     * Compiles the config files
+     *
+     * @throws Exception
+     */
+    public function compileConfigSource()
+    {
+        // compile template
+        if (!is_object($this->compiler_object)) {
+            // load compiler
+            $this->compiler_object = new Smarty_Internal_Config_File_Compiler($this->smarty);
+        }
+        // compile locking
+        if ($this->smarty->compile_locking) {
+            if ($saved_timestamp = $this->getCompiledTimestamp()) {
+                touch($this->getCompiledFilepath());
+            }
+        }
+        // call compiler
+        try {
+            $this->compiler_object->compileSource($this);
+        } catch (Exception $e) {
+            // restore old timestamp in case of error
+            if ($this->smarty->compile_locking && $saved_timestamp) {
+                touch($this->getCompiledFilepath(), $saved_timestamp);
+            }
+            throw $e;
+        }
+        // compiling succeded
+        // write compiled template
+        Smarty_Internal_Write_File::writeFile($this->getCompiledFilepath(), $this->getCompiledConfig(), $this->smarty);
+    }
+
+    /**
+     * load config variables
+     *
+     * @param mixed $sections array of section names, single section or null
+     * @param object $scope global,parent or local
+     */
+    public function loadConfigVars($sections = null, $scope = 'local')
+    {
+        if ($this->data instanceof Smarty_Internal_Template) {
+            $this->data->properties['file_dependency'][sha1($this->source->filepath)] = array($this->source->filepath, $this->source->timestamp, 'file');
+        }
+        if ($this->mustCompile()) {
+            $this->compileConfigSource();
+        }
+        // pointer to scope
+        if ($scope == 'local') {
+            $scope_ptr = $this->data;
+        } elseif ($scope == 'parent') {
+            if (isset($this->data->parent)) {
+                $scope_ptr = $this->data->parent;
+            } else {
+                $scope_ptr = $this->data;
+            }
+        } elseif ($scope == 'root' || $scope == 'global') {
+            $scope_ptr = $this->data;
+            while (isset($scope_ptr->parent)) {
+                $scope_ptr = $scope_ptr->parent;
+            }
+        }
+        $_config_vars = array();
+        include($this->getCompiledFilepath());
+        // copy global config vars
+        foreach ($_config_vars['vars'] as $variable => $value) {
+            if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
+                $scope_ptr->config_vars[$variable] = $value;
+            } else {
+                $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
+            }
+        }
+        // scan sections
+        if (!empty($sections)) {
+            $sections = array_flip((array) $sections);
+            foreach ($_config_vars['sections'] as $this_section => $dummy) {
+                if (isset($sections[$this_section])) {
+                    foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) {
+                        if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
+                            $scope_ptr->config_vars[$variable] = $value;
+                        } else {
+                            $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * set Smarty property in template context
+     *
+     * @param string $property_name property name
+     * @param mixed  $value         value
+     * @throws SmartyException if $property_name is not valid
+     */
+    public function __set($property_name, $value)
+    {
+        switch ($property_name) {
+            case 'source':
+            case 'compiled':
+                $this->$property_name = $value;
+                return;
+        }
+
+        throw new SmartyException("invalid config property '$property_name'.");
+    }
+
+    /**
+     * get Smarty property in template context
+     *
+     * @param string $property_name property name
+     * @throws SmartyException if $property_name is not valid
+     */
+    public function __get($property_name)
+    {
+        switch ($property_name) {
+            case 'source':
+                if (empty($this->config_resource)) {
+                    throw new SmartyException("Unable to parse resource name \"{$this->config_resource}\"");
+                }
+                $this->source = Smarty_Resource::config($this);
+                return $this->source;
+
+            case 'compiled':
+                $this->compiled = $this->source->getCompiled($this);
+                return $this->compiled;
+        }
+
+        throw new SmartyException("config attribute '$property_name' does not exist.");
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config_file_compiler.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config_file_compiler.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_config_file_compiler.php	(revision 345)
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Smarty Internal Plugin Config File Compiler
+ *
+ * This is the config file compiler class. It calls the lexer and parser to
+ * perform the compiling.
+ *
+ * @package Smarty
+ * @subpackage Config
+ * @author Uwe Tews
+ */
+
+/**
+ * Main config file compiler class
+ *
+ * @package Smarty
+ * @subpackage Config
+ */
+class Smarty_Internal_Config_File_Compiler {
+
+    /**
+     * Lexer object
+     *
+     * @var object
+     */
+    public $lex;
+
+    /**
+     * Parser object
+     *
+     * @var object
+     */
+    public $parser;
+
+    /**
+     * Smarty object
+     *
+     * @var Smarty object
+     */
+    public $smarty;
+
+    /**
+     * Smarty object
+     *
+     * @var Smarty_Internal_Config object
+     */
+    public $config;
+
+    /**
+     * Compiled config data sections and variables
+     *
+     * @var array
+     */
+    public $config_data = array();
+
+    /**
+     * Initialize compiler
+     *
+     * @param Smarty $smarty base instance
+     */
+    public function __construct($smarty)
+    {
+        $this->smarty = $smarty;
+        $this->config_data['sections'] = array();
+        $this->config_data['vars'] = array();
+    }
+
+    /**
+     * Method to compile a Smarty template.
+     *
+     * @param  Smarty_Internal_Config $config config object
+     * @return bool true if compiling succeeded, false if it failed
+     */
+    public function compileSource(Smarty_Internal_Config $config)
+    {
+        /* here is where the compiling takes place. Smarty
+          tags in the templates are replaces with PHP code,
+          then written to compiled files. */
+        $this->config = $config;
+        // get config file source
+        $_content = $config->source->content . "\n";
+        // on empty template just return
+        if ($_content == '') {
+            return true;
+        }
+        // init the lexer/parser to compile the config file
+        $lex = new Smarty_Internal_Configfilelexer($_content, $this->smarty);
+        $parser = new Smarty_Internal_Configfileparser($lex, $this);
+        if ($this->smarty->_parserdebug) $parser->PrintTrace();
+        // get tokens from lexer and parse them
+        while ($lex->yylex()) {
+            if ($this->smarty->_parserdebug) echo "<br>Parsing  {$parser->yyTokenName[$lex->token]} Token {$lex->value} Line {$lex->line} \n";
+            $parser->doParse($lex->token, $lex->value);
+        }
+        // finish parsing process
+        $parser->doParse(0, 0);
+        $config->compiled_config = '<?php $_config_vars = ' . var_export($this->config_data, true) . '; ?>';
+    }
+
+    /**
+     * display compiler error messages without dying
+     *
+     * If parameter $args is empty it is a parser detected syntax error.
+     * In this case the parser is called to obtain information about exspected tokens.
+     *
+     * If parameter $args contains a string this is used as error message
+     *
+     * @param string $args individual error message or null
+     */
+    public function trigger_config_file_error($args = null)
+    {
+        $this->lex = Smarty_Internal_Configfilelexer::instance();
+        $this->parser = Smarty_Internal_Configfileparser::instance();
+        // get template source line which has error
+        $line = $this->lex->line;
+        if (isset($args)) {
+            // $line--;
+        }
+        $match = preg_split("/\n/", $this->lex->data);
+        $error_text = "Syntax error in config file '{$this->config->source->filepath}' on line {$line} '{$match[$line-1]}' ";
+        if (isset($args)) {
+            // individual error message
+            $error_text .= $args;
+        } else {
+            // exspected token from parser
+            foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
+                $exp_token = $this->parser->yyTokenName[$token];
+                if (isset($this->lex->smarty_token_names[$exp_token])) {
+                    // token type from lexer
+                    $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
+                } else {
+                    // otherwise internal token name
+                    $expect[] = $this->parser->yyTokenName[$token];
+                }
+            }
+            // output parser error message
+            $error_text .= ' - Unexpected "' . $this->lex->value . '", expected one of: ' . implode(' , ', $expect);
+        }
+        throw new SmartyCompilerException($error_text);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfilelexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfilelexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfilelexer.php	(revision 345)
@@ -0,0 +1,612 @@
+<?php
+/**
+* Smarty Internal Plugin Configfilelexer
+*
+* This is the lexer to break the config file source into tokens
+* @package Smarty
+* @subpackage Config
+* @author Uwe Tews
+*/
+/**
+* Smarty Internal Plugin Configfilelexer
+*/
+class Smarty_Internal_Configfilelexer
+{
+
+    public $data;
+    public $counter;
+    public $token;
+    public $value;
+    public $node;
+    public $line;
+    private $state = 1;
+    public $smarty_token_names = array (		// Text for parser error messages
+   				);
+
+
+    function __construct($data, $smarty)
+    {
+        // set instance object
+        self::instance($this);
+        $this->data = $data . "\n"; //now all lines are \n-terminated
+        $this->counter = 0;
+        $this->line = 1;
+        $this->smarty = $smarty;
+        $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
+    }
+    public static function &instance($new_instance = null)
+    {
+        static $instance = null;
+        if (isset($new_instance) && is_object($new_instance))
+            $instance = $new_instance;
+        return $instance;
+    }
+
+
+
+    private $_yy_state = 1;
+    private $_yy_stack = array();
+
+    function yylex()
+    {
+        return $this->{'yylex' . $this->_yy_state}();
+    }
+
+    function yypushstate($state)
+    {
+        array_push($this->_yy_stack, $this->_yy_state);
+        $this->_yy_state = $state;
+    }
+
+    function yypopstate()
+    {
+        $this->_yy_state = array_pop($this->_yy_stack);
+    }
+
+    function yybegin($state)
+    {
+        $this->_yy_state = $state;
+    }
+
+
+
+
+    function yylex1()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 0,
+              4 => 0,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+              8 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state START');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r1_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const START = 1;
+    function yy_r1_1($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
+    $this->yypushstate(self::COMMENT);
+    }
+    function yy_r1_2($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
+    $this->yypushstate(self::SECTION);
+    }
+    function yy_r1_3($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
+    }
+    function yy_r1_4($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
+    $this->yypushstate(self::VALUE);
+    }
+    function yy_r1_5($yy_subpatterns)
+    {
+
+    return false;
+    }
+    function yy_r1_6($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+    }
+    function yy_r1_7($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_ID;
+    }
+    function yy_r1_8($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
+    }
+
+
+
+    function yylex2()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 0,
+              4 => 0,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+              8 => 0,
+              9 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state VALUE');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r2_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const VALUE = 2;
+    function yy_r2_1($yy_subpatterns)
+    {
+
+    return false;
+    }
+    function yy_r2_2($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
+    $this->yypopstate();
+    }
+    function yy_r2_3($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_INT;
+    $this->yypopstate();
+    }
+    function yy_r2_4($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
+    $this->yypushstate(self::TRIPPLE);
+    }
+    function yy_r2_5($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
+    $this->yypopstate();
+    }
+    function yy_r2_6($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
+    $this->yypopstate();
+    }
+    function yy_r2_7($yy_subpatterns)
+    {
+
+    if (!$this->smarty->config_booleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
+        $this->yypopstate();
+        $this->yypushstate(self::NAKED_STRING_VALUE);
+        return true; //reprocess in new state
+    } else {
+        $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
+        $this->yypopstate();
+    }
+    }
+    function yy_r2_8($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+    $this->yypopstate();
+    }
+    function yy_r2_9($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+    $this->value = "";
+    $this->yypopstate();
+    }
+
+
+
+    function yylex3()
+    {
+        $tokenMap = array (
+              1 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G([^\n]+?(?=[ \t\r]*\n))/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state NAKED_STRING_VALUE');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r3_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const NAKED_STRING_VALUE = 3;
+    function yy_r3_1($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+    $this->yypopstate();
+    }
+
+
+
+    function yylex4()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state COMMENT');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r4_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const COMMENT = 4;
+    function yy_r4_1($yy_subpatterns)
+    {
+
+    return false;
+    }
+    function yy_r4_2($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+    }
+    function yy_r4_3($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+    $this->yypopstate();
+    }
+
+
+
+    function yylex5()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state SECTION');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r5_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const SECTION = 5;
+    function yy_r5_1($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
+    }
+    function yy_r5_2($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
+    $this->yypopstate();
+    }
+
+
+    function yylex6()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state TRIPPLE');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r6_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const TRIPPLE = 6;
+    function yy_r6_1($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
+    $this->yypopstate();
+    $this->yypushstate(self::START);
+    }
+    function yy_r6_2($yy_subpatterns)
+    {
+
+  $to = strlen($this->data);
+  preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+  if (isset($match[0][1])) {
+    $to = $match[0][1];
+  }
+  $this->value = substr($this->data,$this->counter,$to-$this->counter);
+  $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
+    }
+
+
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfileparser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfileparser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_configfileparser.php	(revision 345)
@@ -0,0 +1,921 @@
+<?php
+/**
+* Smarty Internal Plugin Configfileparser
+*
+* This is the config file parser.
+* It is generated from the internal.configfileparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+class TPC_yyToken implements ArrayAccess
+{
+    public $string = '';
+    public $metadata = array();
+
+    function __construct($s, $m = array())
+    {
+        if ($s instanceof TPC_yyToken) {
+            $this->string = $s->string;
+            $this->metadata = $s->metadata;
+        } else {
+            $this->string = (string) $s;
+            if ($m instanceof TPC_yyToken) {
+                $this->metadata = $m->metadata;
+            } elseif (is_array($m)) {
+                $this->metadata = $m;
+            }
+        }
+    }
+
+    function __toString()
+    {
+        return $this->_string;
+    }
+
+    function offsetExists($offset)
+    {
+        return isset($this->metadata[$offset]);
+    }
+
+    function offsetGet($offset)
+    {
+        return $this->metadata[$offset];
+    }
+
+    function offsetSet($offset, $value)
+    {
+        if ($offset === null) {
+            if (isset($value[0])) {
+                $x = ($value instanceof TPC_yyToken) ?
+                    $value->metadata : $value;
+                $this->metadata = array_merge($this->metadata, $x);
+                return;
+            }
+            $offset = count($this->metadata);
+        }
+        if ($value === null) {
+            return;
+        }
+        if ($value instanceof TPC_yyToken) {
+            if ($value->metadata) {
+                $this->metadata[$offset] = $value->metadata;
+            }
+        } elseif ($value) {
+            $this->metadata[$offset] = $value;
+        }
+    }
+
+    function offsetUnset($offset)
+    {
+        unset($this->metadata[$offset]);
+    }
+}
+
+class TPC_yyStackEntry
+{
+    public $stateno;       /* The state-number */
+    public $major;         /* The major token value.  This is the code
+                     ** number for the token at this stack level */
+    public $minor; /* The user-supplied minor token value.  This
+                     ** is the value of the token  */
+};
+
+
+#line 12 "smarty_internal_configfileparser.y"
+class Smarty_Internal_Configfileparser#line 79 "smarty_internal_configfileparser.php"
+{
+#line 14 "smarty_internal_configfileparser.y"
+
+    // states whether the parse was successful or not
+    public $successful = true;
+    public $retvalue = 0;
+    private $lex;
+    private $internalError = false;
+
+    function __construct($lex, $compiler) {
+        // set instance object
+        self::instance($this);
+        $this->lex = $lex;
+        $this->smarty = $compiler->smarty;
+        $this->compiler = $compiler;
+    }
+    public static function &instance($new_instance = null)
+    {
+        static $instance = null;
+        if (isset($new_instance) && is_object($new_instance))
+            $instance = $new_instance;
+        return $instance;
+    }
+
+    private function parse_bool($str) {
+        if (in_array(strtolower($str) ,array('on','yes','true'))) {
+            $res = true;
+        } else {
+            $res = false;
+        }
+        return $res;
+    }
+
+    private static $escapes_single = Array('\\' => '\\',
+                                          '\'' => '\'');
+    private static function parse_single_quoted_string($qstr) {
+        $escaped_string = substr($qstr, 1, strlen($qstr)-2); //remove outer quotes
+
+        $ss = preg_split('/(\\\\.)/', $escaped_string, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+        $str = "";
+        foreach ($ss as $s) {
+            if (strlen($s) === 2 && $s[0] === '\\') {
+                if (isset(self::$escapes_single[$s[1]])) {
+                    $s = self::$escapes_single[$s[1]];
+                }
+             }
+
+             $str .= $s;
+        }
+
+        return $str;
+    }
+
+    private static function parse_double_quoted_string($qstr) {
+        $inner_str = substr($qstr, 1, strlen($qstr)-2);
+        return stripcslashes($inner_str);
+    }
+
+    private static function parse_tripple_double_quoted_string($qstr) {
+        return stripcslashes($qstr);
+    }
+
+    private function set_var(Array $var, Array &$target_array) {
+        $key = $var["key"];
+        $value = $var["value"];
+
+        if ($this->smarty->config_overwrite || !isset($target_array['vars'][$key])) {
+            $target_array['vars'][$key] = $value;
+        } else {
+            settype($target_array['vars'][$key], 'array');
+            $target_array['vars'][$key][] = $value;
+        }
+    }
+
+    private function add_global_vars(Array $vars) {
+        if (!isset($this->compiler->config_data['vars'])) {
+      $this->compiler->config_data['vars'] = Array();
+        }
+        foreach ($vars as $var) {
+            $this->set_var($var, $this->compiler->config_data);
+        }
+    }
+
+    private function add_section_vars($section_name, Array $vars) {
+        if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
+            $this->compiler->config_data['sections'][$section_name]['vars'] = Array();
+        }
+        foreach ($vars as $var) {
+            $this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
+        }
+    }
+#line 173 "smarty_internal_configfileparser.php"
+
+    const TPC_OPENB                          =  1;
+    const TPC_SECTION                        =  2;
+    const TPC_CLOSEB                         =  3;
+    const TPC_DOT                            =  4;
+    const TPC_ID                             =  5;
+    const TPC_EQUAL                          =  6;
+    const TPC_FLOAT                          =  7;
+    const TPC_INT                            =  8;
+    const TPC_BOOL                           =  9;
+    const TPC_SINGLE_QUOTED_STRING           = 10;
+    const TPC_DOUBLE_QUOTED_STRING           = 11;
+    const TPC_TRIPPLE_QUOTES                 = 12;
+    const TPC_TRIPPLE_TEXT                   = 13;
+    const TPC_TRIPPLE_QUOTES_END             = 14;
+    const TPC_NAKED_STRING                   = 15;
+    const TPC_OTHER                          = 16;
+    const TPC_NEWLINE                        = 17;
+    const TPC_COMMENTSTART                   = 18;
+    const YY_NO_ACTION = 60;
+    const YY_ACCEPT_ACTION = 59;
+    const YY_ERROR_ACTION = 58;
+
+    const YY_SZ_ACTTAB = 38;
+static public $yy_action = array(
+ /*     0 */    29,   30,   34,   33,   24,   13,   19,   25,   35,   21,
+ /*    10 */    59,    8,    3,    1,   20,   12,   14,   31,   20,   12,
+ /*    20 */    15,   17,   23,   18,   27,   26,    4,    5,    6,   32,
+ /*    30 */     2,   11,   28,   22,   16,    9,    7,   10,
+    );
+    static public $yy_lookahead = array(
+ /*     0 */     7,    8,    9,   10,   11,   12,    5,   27,   15,   16,
+ /*    10 */    20,   21,   23,   23,   17,   18,   13,   14,   17,   18,
+ /*    20 */    15,    2,   17,    4,   25,   26,    6,    3,    3,   14,
+ /*    30 */    23,    1,   24,   17,    2,   25,   22,   25,
+);
+    const YY_SHIFT_USE_DFLT = -8;
+    const YY_SHIFT_MAX = 19;
+    static public $yy_shift_ofst = array(
+ /*     0 */    -8,    1,    1,    1,   -7,   -3,   -3,   30,   -8,   -8,
+ /*    10 */    -8,   19,    5,    3,   15,   16,   24,   25,   32,   20,
+);
+    const YY_REDUCE_USE_DFLT = -21;
+    const YY_REDUCE_MAX = 10;
+    static public $yy_reduce_ofst = array(
+ /*     0 */   -10,   -1,   -1,   -1,  -20,   10,   12,    8,   14,    7,
+ /*    10 */   -11,
+);
+    static public $yyExpectedTokens = array(
+        /* 0 */ array(),
+        /* 1 */ array(5, 17, 18, ),
+        /* 2 */ array(5, 17, 18, ),
+        /* 3 */ array(5, 17, 18, ),
+        /* 4 */ array(7, 8, 9, 10, 11, 12, 15, 16, ),
+        /* 5 */ array(17, 18, ),
+        /* 6 */ array(17, 18, ),
+        /* 7 */ array(1, ),
+        /* 8 */ array(),
+        /* 9 */ array(),
+        /* 10 */ array(),
+        /* 11 */ array(2, 4, ),
+        /* 12 */ array(15, 17, ),
+        /* 13 */ array(13, 14, ),
+        /* 14 */ array(14, ),
+        /* 15 */ array(17, ),
+        /* 16 */ array(3, ),
+        /* 17 */ array(3, ),
+        /* 18 */ array(2, ),
+        /* 19 */ array(6, ),
+        /* 20 */ array(),
+        /* 21 */ array(),
+        /* 22 */ array(),
+        /* 23 */ array(),
+        /* 24 */ array(),
+        /* 25 */ array(),
+        /* 26 */ array(),
+        /* 27 */ array(),
+        /* 28 */ array(),
+        /* 29 */ array(),
+        /* 30 */ array(),
+        /* 31 */ array(),
+        /* 32 */ array(),
+        /* 33 */ array(),
+        /* 34 */ array(),
+        /* 35 */ array(),
+);
+    static public $yy_default = array(
+ /*     0 */    44,   37,   41,   40,   58,   58,   58,   36,   39,   44,
+ /*    10 */    44,   58,   58,   58,   58,   58,   58,   58,   58,   58,
+ /*    20 */    55,   54,   57,   56,   50,   45,   43,   42,   38,   46,
+ /*    30 */    47,   52,   51,   49,   48,   53,
+);
+    const YYNOCODE = 29;
+    const YYSTACKDEPTH = 100;
+    const YYNSTATE = 36;
+    const YYNRULE = 22;
+    const YYERRORSYMBOL = 19;
+    const YYERRSYMDT = 'yy0';
+    const YYFALLBACK = 0;
+    static public $yyFallback = array(
+    );
+    static function Trace($TraceFILE, $zTracePrompt)
+    {
+        if (!$TraceFILE) {
+            $zTracePrompt = 0;
+        } elseif (!$zTracePrompt) {
+            $TraceFILE = 0;
+        }
+        self::$yyTraceFILE = $TraceFILE;
+        self::$yyTracePrompt = $zTracePrompt;
+    }
+
+    static function PrintTrace()
+    {
+        self::$yyTraceFILE = fopen('php://output', 'w');
+        self::$yyTracePrompt = '<br>';
+    }
+
+    static public $yyTraceFILE;
+    static public $yyTracePrompt;
+    public $yyidx;                    /* Index of top element in stack */
+    public $yyerrcnt;                 /* Shifts left before out of the error */
+    public $yystack = array();  /* The parser's stack */
+
+    public $yyTokenName = array(
+  '$',             'OPENB',         'SECTION',       'CLOSEB',
+  'DOT',           'ID',            'EQUAL',         'FLOAT',
+  'INT',           'BOOL',          'SINGLE_QUOTED_STRING',  'DOUBLE_QUOTED_STRING',
+  'TRIPPLE_QUOTES',  'TRIPPLE_TEXT',  'TRIPPLE_QUOTES_END',  'NAKED_STRING',
+  'OTHER',         'NEWLINE',       'COMMENTSTART',  'error',
+  'start',         'global_vars',   'sections',      'var_list',
+  'section',       'newline',       'var',           'value',
+    );
+
+    static public $yyRuleName = array(
+ /*   0 */ "start ::= global_vars sections",
+ /*   1 */ "global_vars ::= var_list",
+ /*   2 */ "sections ::= sections section",
+ /*   3 */ "sections ::=",
+ /*   4 */ "section ::= OPENB SECTION CLOSEB newline var_list",
+ /*   5 */ "section ::= OPENB DOT SECTION CLOSEB newline var_list",
+ /*   6 */ "var_list ::= var_list newline",
+ /*   7 */ "var_list ::= var_list var",
+ /*   8 */ "var_list ::=",
+ /*   9 */ "var ::= ID EQUAL value",
+ /*  10 */ "value ::= FLOAT",
+ /*  11 */ "value ::= INT",
+ /*  12 */ "value ::= BOOL",
+ /*  13 */ "value ::= SINGLE_QUOTED_STRING",
+ /*  14 */ "value ::= DOUBLE_QUOTED_STRING",
+ /*  15 */ "value ::= TRIPPLE_QUOTES TRIPPLE_TEXT TRIPPLE_QUOTES_END",
+ /*  16 */ "value ::= TRIPPLE_QUOTES TRIPPLE_QUOTES_END",
+ /*  17 */ "value ::= NAKED_STRING",
+ /*  18 */ "value ::= OTHER",
+ /*  19 */ "newline ::= NEWLINE",
+ /*  20 */ "newline ::= COMMENTSTART NEWLINE",
+ /*  21 */ "newline ::= COMMENTSTART NAKED_STRING NEWLINE",
+    );
+
+    function tokenName($tokenType)
+    {
+        if ($tokenType === 0) {
+            return 'End of Input';
+        }
+        if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) {
+            return $this->yyTokenName[$tokenType];
+        } else {
+            return "Unknown";
+        }
+    }
+
+    static function yy_destructor($yymajor, $yypminor)
+    {
+        switch ($yymajor) {
+            default:  break;   /* If no destructor action specified: do nothing */
+        }
+    }
+
+    function yy_pop_parser_stack()
+    {
+        if (!count($this->yystack)) {
+            return;
+        }
+        $yytos = array_pop($this->yystack);
+        if (self::$yyTraceFILE && $this->yyidx >= 0) {
+            fwrite(self::$yyTraceFILE,
+                self::$yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] .
+                    "\n");
+        }
+        $yymajor = $yytos->major;
+        self::yy_destructor($yymajor, $yytos->minor);
+        $this->yyidx--;
+        return $yymajor;
+    }
+
+    function __destruct()
+    {
+        while ($this->yystack !== Array()) {
+            $this->yy_pop_parser_stack();
+        }
+        if (is_resource(self::$yyTraceFILE)) {
+            fclose(self::$yyTraceFILE);
+        }
+    }
+
+    function yy_get_expected_tokens($token)
+    {
+        $state = $this->yystack[$this->yyidx]->stateno;
+        $expected = self::$yyExpectedTokens[$state];
+        if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+            return $expected;
+        }
+        $stack = $this->yystack;
+        $yyidx = $this->yyidx;
+        do {
+            $yyact = $this->yy_find_shift_action($token);
+            if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+                // reduce action
+                $done = 0;
+                do {
+                    if ($done++ == 100) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // too much recursion prevents proper detection
+                        // so give up
+                        return array_unique($expected);
+                    }
+                    $yyruleno = $yyact - self::YYNSTATE;
+                    $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+                    $nextstate = $this->yy_find_reduce_action(
+                        $this->yystack[$this->yyidx]->stateno,
+                        self::$yyRuleInfo[$yyruleno]['lhs']);
+                    if (isset(self::$yyExpectedTokens[$nextstate])) {
+		        $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]);
+                            if (in_array($token,
+                                  self::$yyExpectedTokens[$nextstate], true)) {
+                            $this->yyidx = $yyidx;
+                            $this->yystack = $stack;
+                            return array_unique($expected);
+                        }
+                    }
+                    if ($nextstate < self::YYNSTATE) {
+                        // we need to shift a non-terminal
+                        $this->yyidx++;
+                        $x = new TPC_yyStackEntry;
+                        $x->stateno = $nextstate;
+                        $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+                        $this->yystack[$this->yyidx] = $x;
+                        continue 2;
+                    } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // the last token was just ignored, we can't accept
+                        // by ignoring input, this is in essence ignoring a
+                        // syntax error!
+                        return array_unique($expected);
+                    } elseif ($nextstate === self::YY_NO_ACTION) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // input accepted, but not shifted (I guess)
+                        return $expected;
+                    } else {
+                        $yyact = $nextstate;
+                    }
+                } while (true);
+            }
+            break;
+        } while (true);
+	$this->yyidx = $yyidx;
+	$this->yystack = $stack;
+        return array_unique($expected);
+    }
+
+    function yy_is_expected_token($token)
+    {
+        if ($token === 0) {
+            return true; // 0 is not part of this
+        }
+        $state = $this->yystack[$this->yyidx]->stateno;
+        if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+            return true;
+        }
+        $stack = $this->yystack;
+        $yyidx = $this->yyidx;
+        do {
+            $yyact = $this->yy_find_shift_action($token);
+            if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+                // reduce action
+                $done = 0;
+                do {
+                    if ($done++ == 100) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // too much recursion prevents proper detection
+                        // so give up
+                        return true;
+                    }
+                    $yyruleno = $yyact - self::YYNSTATE;
+                    $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+                    $nextstate = $this->yy_find_reduce_action(
+                        $this->yystack[$this->yyidx]->stateno,
+                        self::$yyRuleInfo[$yyruleno]['lhs']);
+                    if (isset(self::$yyExpectedTokens[$nextstate]) &&
+                          in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        return true;
+                    }
+                    if ($nextstate < self::YYNSTATE) {
+                        // we need to shift a non-terminal
+                        $this->yyidx++;
+                        $x = new TPC_yyStackEntry;
+                        $x->stateno = $nextstate;
+                        $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+                        $this->yystack[$this->yyidx] = $x;
+                        continue 2;
+                    } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        if (!$token) {
+                            // end of input: this is valid
+                            return true;
+                        }
+                        // the last token was just ignored, we can't accept
+                        // by ignoring input, this is in essence ignoring a
+                        // syntax error!
+                        return false;
+                    } elseif ($nextstate === self::YY_NO_ACTION) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // input accepted, but not shifted (I guess)
+                        return true;
+                    } else {
+                        $yyact = $nextstate;
+                    }
+                } while (true);
+            }
+            break;
+        } while (true);
+        $this->yyidx = $yyidx;
+        $this->yystack = $stack;
+        return true;
+    }
+
+   function yy_find_shift_action($iLookAhead)
+    {
+        $stateno = $this->yystack[$this->yyidx]->stateno;
+
+        /* if ($this->yyidx < 0) return self::YY_NO_ACTION;  */
+        if (!isset(self::$yy_shift_ofst[$stateno])) {
+            // no shift actions
+            return self::$yy_default[$stateno];
+        }
+        $i = self::$yy_shift_ofst[$stateno];
+        if ($i === self::YY_SHIFT_USE_DFLT) {
+            return self::$yy_default[$stateno];
+        }
+        if ($iLookAhead == self::YYNOCODE) {
+            return self::YY_NO_ACTION;
+        }
+        $i += $iLookAhead;
+        if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+              self::$yy_lookahead[$i] != $iLookAhead) {
+            if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
+                   && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+                if (self::$yyTraceFILE) {
+                    fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
+                        $this->yyTokenName[$iLookAhead] . " => " .
+                        $this->yyTokenName[$iFallback] . "\n");
+                }
+                return $this->yy_find_shift_action($iFallback);
+            }
+            return self::$yy_default[$stateno];
+        } else {
+            return self::$yy_action[$i];
+        }
+    }
+
+    function yy_find_reduce_action($stateno, $iLookAhead)
+    {
+        /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+        if (!isset(self::$yy_reduce_ofst[$stateno])) {
+            return self::$yy_default[$stateno];
+        }
+        $i = self::$yy_reduce_ofst[$stateno];
+        if ($i == self::YY_REDUCE_USE_DFLT) {
+            return self::$yy_default[$stateno];
+        }
+        if ($iLookAhead == self::YYNOCODE) {
+            return self::YY_NO_ACTION;
+        }
+        $i += $iLookAhead;
+        if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+              self::$yy_lookahead[$i] != $iLookAhead) {
+            return self::$yy_default[$stateno];
+        } else {
+            return self::$yy_action[$i];
+        }
+    }
+
+    function yy_shift($yyNewState, $yyMajor, $yypMinor)
+    {
+        $this->yyidx++;
+        if ($this->yyidx >= self::YYSTACKDEPTH) {
+            $this->yyidx--;
+            if (self::$yyTraceFILE) {
+                fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
+            }
+            while ($this->yyidx >= 0) {
+                $this->yy_pop_parser_stack();
+            }
+#line 125 "smarty_internal_configfileparser.y"
+
+    $this->internalError = true;
+    $this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
+#line 593 "smarty_internal_configfileparser.php"
+            return;
+        }
+        $yytos = new TPC_yyStackEntry;
+        $yytos->stateno = $yyNewState;
+        $yytos->major = $yyMajor;
+        $yytos->minor = $yypMinor;
+        array_push($this->yystack, $yytos);
+        if (self::$yyTraceFILE && $this->yyidx > 0) {
+            fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
+                $yyNewState);
+            fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
+            for($i = 1; $i <= $this->yyidx; $i++) {
+                fprintf(self::$yyTraceFILE, " %s",
+                    $this->yyTokenName[$this->yystack[$i]->major]);
+            }
+            fwrite(self::$yyTraceFILE,"\n");
+        }
+    }
+
+    static public $yyRuleInfo = array(
+  array( 'lhs' => 20, 'rhs' => 2 ),
+  array( 'lhs' => 21, 'rhs' => 1 ),
+  array( 'lhs' => 22, 'rhs' => 2 ),
+  array( 'lhs' => 22, 'rhs' => 0 ),
+  array( 'lhs' => 24, 'rhs' => 5 ),
+  array( 'lhs' => 24, 'rhs' => 6 ),
+  array( 'lhs' => 23, 'rhs' => 2 ),
+  array( 'lhs' => 23, 'rhs' => 2 ),
+  array( 'lhs' => 23, 'rhs' => 0 ),
+  array( 'lhs' => 26, 'rhs' => 3 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 3 ),
+  array( 'lhs' => 27, 'rhs' => 2 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 27, 'rhs' => 1 ),
+  array( 'lhs' => 25, 'rhs' => 1 ),
+  array( 'lhs' => 25, 'rhs' => 2 ),
+  array( 'lhs' => 25, 'rhs' => 3 ),
+    );
+
+    static public $yyReduceMap = array(
+        0 => 0,
+        2 => 0,
+        3 => 0,
+        19 => 0,
+        20 => 0,
+        21 => 0,
+        1 => 1,
+        4 => 4,
+        5 => 5,
+        6 => 6,
+        7 => 7,
+        8 => 8,
+        9 => 9,
+        10 => 10,
+        11 => 11,
+        12 => 12,
+        13 => 13,
+        14 => 14,
+        15 => 15,
+        16 => 16,
+        17 => 17,
+        18 => 17,
+    );
+#line 131 "smarty_internal_configfileparser.y"
+    function yy_r0(){
+    $this->_retvalue = null;
+    }
+#line 666 "smarty_internal_configfileparser.php"
+#line 136 "smarty_internal_configfileparser.y"
+    function yy_r1(){
+    $this->add_global_vars($this->yystack[$this->yyidx + 0]->minor); $this->_retvalue = null;
+    }
+#line 671 "smarty_internal_configfileparser.php"
+#line 149 "smarty_internal_configfileparser.y"
+    function yy_r4(){
+    $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor);
+    $this->_retvalue = null;
+    }
+#line 677 "smarty_internal_configfileparser.php"
+#line 154 "smarty_internal_configfileparser.y"
+    function yy_r5(){
+    if ($this->smarty->config_read_hidden) {
+        $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor);
+    }
+    $this->_retvalue = null;
+    }
+#line 685 "smarty_internal_configfileparser.php"
+#line 162 "smarty_internal_configfileparser.y"
+    function yy_r6(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+    }
+#line 690 "smarty_internal_configfileparser.php"
+#line 166 "smarty_internal_configfileparser.y"
+    function yy_r7(){
+    $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor, Array($this->yystack[$this->yyidx + 0]->minor));
+    }
+#line 695 "smarty_internal_configfileparser.php"
+#line 170 "smarty_internal_configfileparser.y"
+    function yy_r8(){
+    $this->_retvalue = Array();
+    }
+#line 700 "smarty_internal_configfileparser.php"
+#line 176 "smarty_internal_configfileparser.y"
+    function yy_r9(){
+    $this->_retvalue = Array("key" => $this->yystack[$this->yyidx + -2]->minor, "value" => $this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 705 "smarty_internal_configfileparser.php"
+#line 181 "smarty_internal_configfileparser.y"
+    function yy_r10(){
+    $this->_retvalue = (float) $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 710 "smarty_internal_configfileparser.php"
+#line 185 "smarty_internal_configfileparser.y"
+    function yy_r11(){
+    $this->_retvalue = (int) $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 715 "smarty_internal_configfileparser.php"
+#line 189 "smarty_internal_configfileparser.y"
+    function yy_r12(){
+    $this->_retvalue = $this->parse_bool($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 720 "smarty_internal_configfileparser.php"
+#line 193 "smarty_internal_configfileparser.y"
+    function yy_r13(){
+    $this->_retvalue = self::parse_single_quoted_string($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 725 "smarty_internal_configfileparser.php"
+#line 197 "smarty_internal_configfileparser.y"
+    function yy_r14(){
+    $this->_retvalue = self::parse_double_quoted_string($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 730 "smarty_internal_configfileparser.php"
+#line 201 "smarty_internal_configfileparser.y"
+    function yy_r15(){
+    $this->_retvalue = self::parse_tripple_double_quoted_string($this->yystack[$this->yyidx + -1]->minor);
+    }
+#line 735 "smarty_internal_configfileparser.php"
+#line 205 "smarty_internal_configfileparser.y"
+    function yy_r16(){
+    $this->_retvalue = '';
+    }
+#line 740 "smarty_internal_configfileparser.php"
+#line 209 "smarty_internal_configfileparser.y"
+    function yy_r17(){
+    $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 745 "smarty_internal_configfileparser.php"
+
+    private $_retvalue;
+
+    function yy_reduce($yyruleno)
+    {
+        $yymsp = $this->yystack[$this->yyidx];
+        if (self::$yyTraceFILE && $yyruleno >= 0
+              && $yyruleno < count(self::$yyRuleName)) {
+            fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
+                self::$yyTracePrompt, $yyruleno,
+                self::$yyRuleName[$yyruleno]);
+        }
+
+        $this->_retvalue = $yy_lefthand_side = null;
+        if (array_key_exists($yyruleno, self::$yyReduceMap)) {
+            // call the action
+            $this->_retvalue = null;
+            $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+            $yy_lefthand_side = $this->_retvalue;
+        }
+        $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
+        $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
+        $this->yyidx -= $yysize;
+        for($i = $yysize; $i; $i--) {
+            // pop all of the right-hand side parameters
+            array_pop($this->yystack);
+        }
+        $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+        if ($yyact < self::YYNSTATE) {
+            if (!self::$yyTraceFILE && $yysize) {
+                $this->yyidx++;
+                $x = new TPC_yyStackEntry;
+                $x->stateno = $yyact;
+                $x->major = $yygoto;
+                $x->minor = $yy_lefthand_side;
+                $this->yystack[$this->yyidx] = $x;
+            } else {
+                $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+            }
+        } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+            $this->yy_accept();
+        }
+    }
+
+    function yy_parse_failed()
+    {
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
+        }
+        while ($this->yyidx >= 0) {
+            $this->yy_pop_parser_stack();
+        }
+    }
+
+    function yy_syntax_error($yymajor, $TOKEN)
+    {
+#line 118 "smarty_internal_configfileparser.y"
+
+    $this->internalError = true;
+    $this->yymajor = $yymajor;
+    $this->compiler->trigger_config_file_error();
+#line 808 "smarty_internal_configfileparser.php"
+    }
+
+    function yy_accept()
+    {
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
+        }
+        while ($this->yyidx >= 0) {
+            $stack = $this->yy_pop_parser_stack();
+        }
+#line 110 "smarty_internal_configfileparser.y"
+
+    $this->successful = !$this->internalError;
+    $this->internalError = false;
+    $this->retvalue = $this->_retvalue;
+    //echo $this->retvalue."\n\n";
+#line 826 "smarty_internal_configfileparser.php"
+    }
+
+    function doParse($yymajor, $yytokenvalue)
+    {
+        $yyerrorhit = 0;   /* True if yymajor has invoked an error */
+
+        if ($this->yyidx === null || $this->yyidx < 0) {
+            $this->yyidx = 0;
+            $this->yyerrcnt = -1;
+            $x = new TPC_yyStackEntry;
+            $x->stateno = 0;
+            $x->major = 0;
+            $this->yystack = array();
+            array_push($this->yystack, $x);
+        }
+        $yyendofinput = ($yymajor==0);
+
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sInput %s\n",
+                self::$yyTracePrompt, $this->yyTokenName[$yymajor]);
+        }
+
+        do {
+            $yyact = $this->yy_find_shift_action($yymajor);
+            if ($yymajor < self::YYERRORSYMBOL &&
+                  !$this->yy_is_expected_token($yymajor)) {
+                // force a syntax error
+                $yyact = self::YY_ERROR_ACTION;
+            }
+            if ($yyact < self::YYNSTATE) {
+                $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+                $this->yyerrcnt--;
+                if ($yyendofinput && $this->yyidx >= 0) {
+                    $yymajor = 0;
+                } else {
+                    $yymajor = self::YYNOCODE;
+                }
+            } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+                $this->yy_reduce($yyact - self::YYNSTATE);
+            } elseif ($yyact == self::YY_ERROR_ACTION) {
+                if (self::$yyTraceFILE) {
+                    fprintf(self::$yyTraceFILE, "%sSyntax Error!\n",
+                        self::$yyTracePrompt);
+                }
+                if (self::YYERRORSYMBOL) {
+                    if ($this->yyerrcnt < 0) {
+                        $this->yy_syntax_error($yymajor, $yytokenvalue);
+                    }
+                    $yymx = $this->yystack[$this->yyidx]->major;
+                    if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){
+                        if (self::$yyTraceFILE) {
+                            fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n",
+                                self::$yyTracePrompt, $this->yyTokenName[$yymajor]);
+                        }
+                        $this->yy_destructor($yymajor, $yytokenvalue);
+                        $yymajor = self::YYNOCODE;
+                    } else {
+                        while ($this->yyidx >= 0 &&
+                                 $yymx != self::YYERRORSYMBOL &&
+        ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
+                              ){
+                            $this->yy_pop_parser_stack();
+                        }
+                        if ($this->yyidx < 0 || $yymajor==0) {
+                            $this->yy_destructor($yymajor, $yytokenvalue);
+                            $this->yy_parse_failed();
+                            $yymajor = self::YYNOCODE;
+                        } elseif ($yymx != self::YYERRORSYMBOL) {
+                            $u2 = 0;
+                            $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+                        }
+                    }
+                    $this->yyerrcnt = 3;
+                    $yyerrorhit = 1;
+                } else {
+                    if ($this->yyerrcnt <= 0) {
+                        $this->yy_syntax_error($yymajor, $yytokenvalue);
+                    }
+                    $this->yyerrcnt = 3;
+                    $this->yy_destructor($yymajor, $yytokenvalue);
+                    if ($yyendofinput) {
+                        $this->yy_parse_failed();
+                    }
+                    $yymajor = self::YYNOCODE;
+                }
+            } else {
+                $this->yy_accept();
+                $yymajor = self::YYNOCODE;
+            }
+        } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+    }
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_data.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_data.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_data.php	(revision 345)
@@ -0,0 +1,551 @@
+<?php
+/**
+ * Smarty Internal Plugin Data
+ *
+ * This file contains the basic classes and methodes for template and variable creation
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Base class with template and variable methodes
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Internal_Data {
+
+    /**
+     * name of class used for templates
+     *
+     * @var string
+     */
+    public $template_class = 'Smarty_Internal_Template';
+    /**
+     * template variables
+     *
+     * @var array
+     */
+    public $tpl_vars = array();
+    /**
+     * parent template (if any)
+     *
+     * @var Smarty_Internal_Template
+     */
+    public $parent = null;
+    /**
+     * configuration settings
+     *
+     * @var array
+     */
+    public $config_vars = array();
+
+    /**
+     * assigns a Smarty variable
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed        $value   the value to assign
+     * @param boolean      $nocache if true any output of this variable will be not cached
+     * @param boolean $scope the scope the variable will have  (local,parent or root)
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function assign($tpl_var, $value = null, $nocache = false)
+    {
+        if (is_array($tpl_var)) {
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    $this->tpl_vars[$_key] = new Smarty_variable($_val, $nocache);
+                }
+            }
+        } else {
+            if ($tpl_var != '') {
+                $this->tpl_vars[$tpl_var] = new Smarty_variable($value, $nocache);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * assigns a global Smarty variable
+     *
+     * @param string $varname the global variable name
+     * @param mixed  $value   the value to assign
+     * @param boolean $nocache if true any output of this variable will be not cached
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function assignGlobal($varname, $value = null, $nocache = false)
+    {
+        if ($varname != '') {
+            Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache);
+        }
+
+        return $this;
+    }
+    /**
+     * assigns values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $ &$value the referenced value to assign
+     * @param boolean $nocache if true any output of this variable will be not cached
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function assignByRef($tpl_var, &$value, $nocache = false)
+    {
+        if ($tpl_var != '') {
+            $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
+            $this->tpl_vars[$tpl_var]->value = &$value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * appends values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed        $value   the value to append
+     * @param boolean      $merge   flag if array elements shall be merged
+     * @param boolean $nocache if true any output of this variable will be not cached
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function append($tpl_var, $value = null, $merge = false, $nocache = false)
+    {
+        if (is_array($tpl_var)) {
+            // $tpl_var is an array, ignore $value
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    if (!isset($this->tpl_vars[$_key])) {
+                        $tpl_var_inst = $this->getVariable($_key, null, true, false);
+                        if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
+                            $this->tpl_vars[$_key] = new Smarty_variable(null, $nocache);
+                        } else {
+                            $this->tpl_vars[$_key] = clone $tpl_var_inst;
+                        }
+                    }
+                    if (!(is_array($this->tpl_vars[$_key]->value) || $this->tpl_vars[$_key]->value instanceof ArrayAccess)) {
+                        settype($this->tpl_vars[$_key]->value, 'array');
+                    }
+                    if ($merge && is_array($_val)) {
+                        foreach($_val as $_mkey => $_mval) {
+                            $this->tpl_vars[$_key]->value[$_mkey] = $_mval;
+                        }
+                    } else {
+                        $this->tpl_vars[$_key]->value[] = $_val;
+                    }
+                }
+            }
+        } else {
+            if ($tpl_var != '' && isset($value)) {
+                if (!isset($this->tpl_vars[$tpl_var])) {
+                    $tpl_var_inst = $this->getVariable($tpl_var, null, true, false);
+                    if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
+                        $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
+                    } else {
+                        $this->tpl_vars[$tpl_var] = clone $tpl_var_inst;
+                    }
+                }
+                if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
+                    settype($this->tpl_vars[$tpl_var]->value, 'array');
+                }
+                if ($merge && is_array($value)) {
+                    foreach($value as $_mkey => $_mval) {
+                        $this->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
+                    }
+                } else {
+                    $this->tpl_vars[$tpl_var]->value[] = $value;
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * appends values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed  &$value  the referenced value to append
+     * @param boolean $merge  flag if array elements shall be merged
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function appendByRef($tpl_var, &$value, $merge = false)
+    {
+        if ($tpl_var != '' && isset($value)) {
+            if (!isset($this->tpl_vars[$tpl_var])) {
+                $this->tpl_vars[$tpl_var] = new Smarty_variable();
+            }
+            if (!is_array($this->tpl_vars[$tpl_var]->value)) {
+                settype($this->tpl_vars[$tpl_var]->value, 'array');
+            }
+            if ($merge && is_array($value)) {
+                foreach($value as $_key => $_val) {
+                    $this->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key];
+                }
+            } else {
+                $this->tpl_vars[$tpl_var]->value[] = &$value;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns a single or all template variables
+     *
+     * @param string  $varname        variable name or null
+     * @param string  $_ptr           optional pointer to data object
+     * @param boolean $search_parents include parent templates?
+     * @return string variable value or or array of variables
+     */
+    public function getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
+    {
+        if (isset($varname)) {
+            $_var = $this->getVariable($varname, $_ptr, $search_parents, false);
+            if (is_object($_var)) {
+                return $_var->value;
+            } else {
+                return null;
+            }
+        } else {
+            $_result = array();
+            if ($_ptr === null) {
+                $_ptr = $this;
+            } while ($_ptr !== null) {
+                foreach ($_ptr->tpl_vars AS $key => $var) {
+                    if (!array_key_exists($key, $_result)) {
+                        $_result[$key] = $var->value;
+                    }
+                }
+                // not found, try at parent
+                if ($search_parents) {
+                    $_ptr = $_ptr->parent;
+                } else {
+                    $_ptr = null;
+                }
+            }
+            if ($search_parents && isset(Smarty::$global_tpl_vars)) {
+                foreach (Smarty::$global_tpl_vars AS $key => $var) {
+                    if (!array_key_exists($key, $_result)) {
+                        $_result[$key] = $var->value;
+                    }
+                }
+            }
+            return $_result;
+        }
+    }
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string|array $tpl_var the template variable(s) to clear
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function clearAssign($tpl_var)
+    {
+        if (is_array($tpl_var)) {
+            foreach ($tpl_var as $curr_var) {
+                unset($this->tpl_vars[$curr_var]);
+            }
+        } else {
+            unset($this->tpl_vars[$tpl_var]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * clear all the assigned template variables.
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function clearAllAssign()
+    {
+        $this->tpl_vars = array();
+        return $this;
+    }
+
+    /**
+     * load a config file, optionally load just selected sections
+     *
+     * @param string $config_file filename
+     * @param mixed  $sections    array of section names, single section or null
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function configLoad($config_file, $sections = null)
+    {
+        // load Config class
+        $config = new Smarty_Internal_Config($config_file, $this->smarty, $this);
+        $config->loadConfigVars($sections);
+        return $this;
+    }
+
+    /**
+     * gets the object of a Smarty variable
+     *
+     * @param string  $variable the name of the Smarty variable
+     * @param object  $_ptr     optional pointer to data object
+     * @param boolean $search_parents search also in parent data
+     * @return object the object of the variable
+     */
+    public function getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
+    {
+        if ($_ptr === null) {
+            $_ptr = $this;
+        } while ($_ptr !== null) {
+            if (isset($_ptr->tpl_vars[$variable])) {
+                // found it, return it
+                return $_ptr->tpl_vars[$variable];
+            }
+            // not found, try at parent
+            if ($search_parents) {
+                $_ptr = $_ptr->parent;
+            } else {
+                $_ptr = null;
+            }
+        }
+        if (isset(Smarty::$global_tpl_vars[$variable])) {
+            // found it, return it
+            return Smarty::$global_tpl_vars[$variable];
+        }
+        if ($this->smarty->error_unassigned && $error_enable) {
+            // force a notice
+            $x = $$variable;
+        }
+        return new Undefined_Smarty_Variable;
+    }
+
+    /**
+     * gets  a config variable
+     *
+     * @param string $variable the name of the config variable
+     * @return mixed the value of the config variable
+     */
+    public function getConfigVariable($variable, $error_enable = true)
+    {
+        $_ptr = $this;
+        while ($_ptr !== null) {
+            if (isset($_ptr->config_vars[$variable])) {
+                // found it, return it
+                return $_ptr->config_vars[$variable];
+            }
+            // not found, try at parent
+            $_ptr = $_ptr->parent;
+        }
+        if ($this->smarty->error_unassigned && $error_enable) {
+            // force a notice
+            $x = $$variable;
+        }
+        return null;
+    }
+
+    /**
+     * gets  a stream variable
+     *
+     * @param string $variable the stream of the variable
+     * @return mixed the value of the stream variable
+     */
+    public function getStreamVariable($variable)
+    {
+        $_result = '';
+        $fp = fopen($variable, 'r+');
+        if ($fp) {
+            while (!feof($fp) && ($current_line = fgets($fp)) !== false ) {
+                $_result .= $current_line;
+            }
+            fclose($fp);
+            return $_result;
+        }
+
+        if ($this->smarty->error_unassigned) {
+            throw new SmartyException('Undefined stream variable "' . $variable . '"');
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns a single or all config variables
+     *
+     * @param string $varname variable name or null
+     * @return string variable value or or array of variables
+     */
+    public function getConfigVars($varname = null, $search_parents = true)
+    {
+        $_ptr = $this;
+        $var_array = array();
+        while ($_ptr !== null) {
+            if (isset($varname)) {
+                if (isset($_ptr->config_vars[$varname])) {
+                    return $_ptr->config_vars[$varname];
+                }
+            } else {
+                $var_array = array_merge($_ptr->config_vars, $var_array);
+            }
+             // not found, try at parent
+            if ($search_parents) {
+                $_ptr = $_ptr->parent;
+            } else {
+                $_ptr = null;
+            }
+        }
+        if (isset($varname)) {
+            return '';
+        } else {
+            return $var_array;
+        }
+    }
+
+    /**
+     * Deassigns a single or all config variables
+     *
+     * @param string $varname variable name or null
+     * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function clearConfig($varname = null)
+    {
+        if (isset($varname)) {
+            unset($this->config_vars[$varname]);
+        } else {
+            $this->config_vars = array();
+        }
+        return $this;
+    }
+
+}
+
+/**
+ * class for the Smarty data object
+ *
+ * The Smarty data object will hold Smarty variables in the current scope
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Data extends Smarty_Internal_Data {
+
+    /**
+     * Smarty object
+     *
+     * @var Smarty
+     */
+    public $smarty = null;
+
+    /**
+     * create Smarty data object
+     *
+     * @param Smarty|array $_parent  parent template
+     * @param Smarty       $smarty   global smarty instance
+     */
+    public function __construct ($_parent = null, $smarty = null)
+    {
+        $this->smarty = $smarty;
+        if (is_object($_parent)) {
+            // when object set up back pointer
+            $this->parent = $_parent;
+        } elseif (is_array($_parent)) {
+            // set up variable values
+            foreach ($_parent as $_key => $_val) {
+                $this->tpl_vars[$_key] = new Smarty_variable($_val);
+            }
+        } elseif ($_parent != null) {
+            throw new SmartyException("Wrong type for template variables");
+        }
+    }
+
+}
+
+/**
+ * class for the Smarty variable object
+ *
+ * This class defines the Smarty variable object
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Variable {
+
+    /**
+     * template variable
+     *
+     * @var mixed
+     */
+    public $value = null;
+    /**
+     * if true any output of this variable will be not cached
+     *
+     * @var boolean
+     */
+    public $nocache = false;
+    /**
+     * the scope the variable will have  (local,parent or root)
+     *
+     * @var int
+     */
+    public $scope = Smarty::SCOPE_LOCAL;
+
+    /**
+     * create Smarty variable object
+     *
+     * @param mixed   $value   the value to assign
+     * @param boolean $nocache if true any output of this variable will be not cached
+     * @param int     $scope   the scope the variable will have  (local,parent or root)
+     */
+    public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
+    {
+        $this->value = $value;
+        $this->nocache = $nocache;
+        $this->scope = $scope;
+    }
+
+    /**
+     * <<magic>> String conversion
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->value;
+    }
+
+}
+
+/**
+ * class for undefined variable object
+ *
+ * This class defines an object for undefined variable handling
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Undefined_Smarty_Variable {
+
+    /**
+     * Returns FALSE for 'nocache' and NULL otherwise.
+     *
+     * @param string $name
+     * @return bool
+     */
+    public function __get($name)
+    {
+        if ($name == 'nocache') {
+            return false;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Always returns an empty string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return "";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_debug.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_debug.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_debug.php	(revision 345)
@@ -0,0 +1,206 @@
+<?php
+/**
+ * Smarty Internal Plugin Debug
+ *
+ * Class to collect data for the Smarty Debugging Consol
+ *
+ * @package Smarty
+ * @subpackage Debug
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Debug Class
+ *
+ * @package Smarty
+ * @subpackage Debug
+ */
+class Smarty_Internal_Debug extends Smarty_Internal_Data {
+
+    /**
+     * template data
+     *
+     * @var array
+     */
+    public static $template_data = array();
+
+    /**
+     * Start logging of compile time
+     *
+     * @param object $template
+     */
+    public static function start_compile($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['start_time'] = microtime(true);
+    }
+
+    /**
+     * End logging of compile time
+     *
+     * @param object $template
+     */
+    public static function end_compile($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['compile_time'] += microtime(true) - self::$template_data[$key]['start_time'];
+    }
+
+    /**
+     * Start logging of render time
+     *
+     * @param object $template
+     */
+    public static function start_render($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['start_time'] = microtime(true);
+    }
+
+    /**
+     * End logging of compile time
+     *
+     * @param object $template
+     */
+    public static function end_render($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['render_time'] += microtime(true) - self::$template_data[$key]['start_time'];
+    }
+
+    /**
+     * Start logging of cache time
+     *
+     * @param object $template cached template
+     */
+    public static function start_cache($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['start_time'] = microtime(true);
+    }
+
+    /**
+     * End logging of cache time
+     *
+     * @param object $template cached template
+     */
+    public static function end_cache($template)
+    {
+        $key = self::get_key($template);
+        self::$template_data[$key]['cache_time'] += microtime(true) - self::$template_data[$key]['start_time'];
+    }
+
+    /**
+     * Opens a window for the Smarty Debugging Consol and display the data
+     *
+     * @param Smarty_Internal_Template|Smarty $obj object to debug
+     */
+    public static function display_debug($obj)
+    {
+        // prepare information of assigned variables
+        $ptr = self::get_debug_vars($obj);
+        if ($obj instanceof Smarty) {
+            $smarty = clone $obj;
+        } else {
+            $smarty = clone $obj->smarty;
+        }
+        $_assigned_vars = $ptr->tpl_vars;
+        ksort($_assigned_vars);
+        $_config_vars = $ptr->config_vars;
+        ksort($_config_vars);
+        $smarty->registered_filters = array();
+        $smarty->autoload_filters = array();
+        $smarty->default_modifiers = array();
+        $smarty->force_compile = false;
+        $smarty->left_delimiter = '{';
+        $smarty->right_delimiter = '}';
+        $smarty->debugging = false;
+        $smarty->force_compile = false;
+        $_template = new Smarty_Internal_Template($smarty->debug_tpl, $smarty);
+        $_template->caching = false;
+        $_template->disableSecurity();
+        $_template->cache_id = null;
+        $_template->compile_id = null;
+        if ($obj instanceof Smarty_Internal_Template) {
+            $_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
+        }
+        if ($obj instanceof Smarty) {
+            $_template->assign('template_data', self::$template_data);
+        } else {
+            $_template->assign('template_data', null);
+        }
+        $_template->assign('assigned_vars', $_assigned_vars);
+        $_template->assign('config_vars', $_config_vars);
+        $_template->assign('execution_time', microtime(true) - $smarty->start_time);
+        echo $_template->fetch();
+    }
+
+    /**
+     * Recursively gets variables from all template/data scopes
+     *
+     * @param Smarty_Internal_Template|Smarty_Data $obj object to debug
+     * @return StdClass
+     */
+    public static function get_debug_vars($obj)
+    {
+        $config_vars = $obj->config_vars;
+        $tpl_vars = array();
+        foreach ($obj->tpl_vars as $key => $var) {
+            $tpl_vars[$key] = clone $var;
+            if ($obj instanceof Smarty_Internal_Template) {
+                $tpl_vars[$key]->scope = $obj->source->type . ':' . $obj->source->name;
+            } elseif ($obj instanceof Smarty_Data) {
+                $tpl_vars[$key]->scope = 'Data object';
+            } else {
+                $tpl_vars[$key]->scope = 'Smarty root';
+            }
+        }
+
+        if (isset($obj->parent)) {
+            $parent = self::get_debug_vars($obj->parent);
+            $tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
+            $config_vars = array_merge($parent->config_vars, $config_vars);
+        } else {
+            foreach (Smarty::$global_tpl_vars as $name => $var) {
+                if (!array_key_exists($name, $tpl_vars)) {
+                    $clone = clone $var;
+                    $clone->scope = 'Global';
+                    $tpl_vars[$name] = $clone;
+                }
+            }
+        }
+        return (object) array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
+    }
+
+    /**
+     * Return key into $template_data for template
+     *
+     * @param object $template  template object
+     * @return string   key into $template_data
+     */
+    private static function get_key($template)
+    {
+        static $_is_stringy = array('string' => true, 'eval' => true);
+        // calculate Uid if not already done
+        if ($template->source->uid == '') {
+            $template->source->filepath;
+        }
+        $key = $template->source->uid;
+        if (isset(self::$template_data[$key])) {
+            return $key;
+        } else {
+            if (isset($_is_stringy[$template->source->type])) {
+                self::$template_data[$key]['name'] = '\''.substr($template->source->name,0,25).'...\'';
+            } else {
+                self::$template_data[$key]['name'] = $template->source->filepath;
+            }
+            self::$template_data[$key]['compile_time'] = 0;
+            self::$template_data[$key]['render_time'] = 0;
+            self::$template_data[$key]['cache_time'] = 0;
+            return $key;
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_filter_handler.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_filter_handler.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_filter_handler.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Smarty Internal Plugin Filter Handler
+ *
+ * Smarty filter handler class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Uwe Tews
+ */
+
+/**
+ * Class for filter processing
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Filter_Handler {
+
+    /**
+     * Run filters over content
+     *
+     * The filters will be lazy loaded if required
+     * class name format: Smarty_FilterType_FilterName
+     * plugin filename format: filtertype.filtername.php
+     * Smarty2 filter plugins could be used
+     *
+     * @param string                   $type     the type of filter ('pre','post','output') which shall run
+     * @param string                   $content  the content which shall be processed by the filters
+     * @param Smarty_Internal_Template $template template object
+     * @return string the filtered content
+     */
+    public static function runFilter($type, $content, Smarty_Internal_Template $template)
+    {
+        $output = $content;
+        // loop over autoload filters of specified type
+        if (!empty($template->smarty->autoload_filters[$type])) {
+            foreach ((array)$template->smarty->autoload_filters[$type] as $name) {
+                $plugin_name = "Smarty_{$type}filter_{$name}";
+                if ($template->smarty->loadPlugin($plugin_name)) {
+                    if (function_exists($plugin_name)) {
+                        // use loaded Smarty2 style plugin
+                        $output = $plugin_name($output, $template);
+                    } elseif (class_exists($plugin_name, false)) {
+                        // loaded class of filter plugin
+                        $output = call_user_func(array($plugin_name, 'execute'), $output, $template);
+                    }
+                } else {
+                    // nothing found, throw exception
+                    throw new SmartyException("Unable to load filter {$plugin_name}");
+                }
+            }
+        }
+        // loop over registerd filters of specified type
+        if (!empty($template->smarty->registered_filters[$type])) {
+            foreach ($template->smarty->registered_filters[$type] as $key => $name) {
+                if (is_array($template->smarty->registered_filters[$type][$key])) {
+                    $output = call_user_func($template->smarty->registered_filters[$type][$key], $output, $template);
+                } else {
+                    $output = $template->smarty->registered_filters[$type][$key]($output, $template);
+                }
+            }
+        }
+        // return filtered output
+        return $output;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_function_call_handler.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_function_call_handler.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_function_call_handler.php	(revision 345)
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Smarty Internal Plugin Function Call Handler
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Uwe Tews
+ */
+
+/**
+ * This class does call function defined with the {function} tag
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Function_Call_Handler {
+
+    /**
+     * This function handles calls to template functions defined by {function}
+     * It does create a PHP function at the first call
+     *
+     * @param string                   $_name       template function name
+     * @param Smarty_Internal_Template $_template   template object
+     * @param array                    $_params     Smarty variables passed as call parameter
+     * @param string                   $_hash       nocache hash value
+     * @param bool                     $_nocache    nocache flag
+     */
+    public static function call($_name, Smarty_Internal_Template $_template, $_params, $_hash, $_nocache)
+    {
+        if ($_nocache) {
+            $_function = "smarty_template_function_{$_name}_nocache";
+        } else {
+            $_function = "smarty_template_function_{$_hash}_{$_name}";
+        }
+        if (!is_callable($_function)) {
+            $_code = "function {$_function}(\$_smarty_tpl,\$params) {
+    \$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
+    foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
+    foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
+            if ($_nocache) {
+                $_code .= preg_replace(array("!<\?php echo \\'/\*%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/|/\*/%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/\\';\?>!",
+                        "!\\\'!"), array('', "'"), $_template->smarty->template_functions[$_name]['compiled']);
+                $_template->smarty->template_functions[$_name]['called_nocache'] = true;
+            } else {
+                $_code .= preg_replace("/{$_template->smarty->template_functions[$_name]['nocache_hash']}/", $_template->properties['nocache_hash'], $_template->smarty->template_functions[$_name]['compiled']);
+            }
+            $_code .= "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}";
+            eval($_code);
+        }
+        $_function($_template, $_params);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_get_include_path.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_get_include_path.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_get_include_path.php	(revision 345)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty read include path plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Monte Ohrt
+ */
+
+/**
+ * Smarty Internal Read Include Path Class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Get_Include_Path {
+
+    /**
+     * Return full file path from PHP include_path
+     *
+     * @param string $filepath filepath
+     * @return string|boolean full filepath or false
+     */
+    public static function getIncludePath($filepath)
+    {
+        static $_include_path = null;
+
+        if ($_path_array === null) {
+            $_include_path = explode(PATH_SEPARATOR, get_include_path());
+        }
+
+        foreach ($_include_path as $_path) {
+            if (file_exists($_path . DS . $filepath)) {
+                return $_path . DS . $filepath;
+            }
+        }
+        
+        return false;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_nocache_insert.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_nocache_insert.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_nocache_insert.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Smarty Internal Plugin Nocache Insert
+ *
+ * Compiles the {insert} tag into the cache file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Nocache_Insert {
+
+    /**
+     * Compiles code for the {insert} tag into cache file
+     *
+     * @param string                   $_function insert function name
+     * @param array                    $_attr     array with parameter
+     * @param Smarty_Internal_Template $_template template object
+     * @param string                   $_script   script name to load or 'null'
+     * @param string                   $_assign   optional variable name
+     * @return string compiled code
+     */
+    public static function compile($_function, $_attr, $_template, $_script, $_assign = null)
+    {
+        $_output = '<?php ';
+        if ($_script != 'null') {
+            // script which must be included
+            // code for script file loading
+            $_output .= "require_once '{$_script}';";
+        }
+        // call insert
+        if (isset($_assign)) {
+            $_output .= "\$_smarty_tpl->assign('{$_assign}' , {$_function} (" . var_export($_attr, true) . ",\$_smarty_tpl), true);?>";
+        } else {
+            $_output .= "echo {$_function}(" . var_export($_attr, true) . ",\$_smarty_tpl);?>";
+        }
+        $_tpl = $_template;
+        while ($_tpl->parent instanceof Smarty_Internal_Template) {
+            $_tpl = $_tpl->parent;
+        }
+        return "/*%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/" . $_output . "/*/%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/";
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_parsetree.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_parsetree.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_parsetree.php	(revision 345)
@@ -0,0 +1,395 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parsetrees
+ *
+ * These are classes to build parsetrees in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+abstract class _smarty_parsetree {
+
+    /**
+     * Parser object
+     * @var object
+     */
+    public $parser;
+    /**
+     * Buffer content
+     * @var mixed
+     */
+    public $data;
+
+    /**
+     * Return buffer
+     *
+     * @return string  buffer content
+     */
+    abstract public function to_smarty_php();
+
+}
+
+/**
+ * A complete smarty tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_tag extends _smarty_parsetree {
+
+    /**
+     * Saved block nesting level
+     * @var int
+     */
+    public $saved_block_nesting;
+
+    /**
+     * Create parse tree buffer for Smarty tag
+     *
+     * @param object $parser    parser object
+     * @param string $data      content
+     */
+    public function __construct($parser, $data)
+    {
+        $this->parser = $parser;
+        $this->data = $data;
+        $this->saved_block_nesting = $parser->block_nesting_level;
+    }
+
+    /**
+     * Return buffer content
+     *
+     * @return string  content
+     */
+    public function to_smarty_php()
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return complied code that loads the evaluated outout of buffer content into a temporary variable
+     *
+     * @return string template code
+     */
+    public function assign_to_var()
+    {
+        $var = sprintf('$_tmp%d', ++$this->parser->prefix_number);
+        $this->parser->compiler->prefix_code[] = sprintf('<?php ob_start();?>%s<?php %s=ob_get_clean();?>', $this->data, $var);
+        return $var;
+    }
+
+}
+
+/**
+ * Code fragment inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_code extends _smarty_parsetree {
+
+
+    /**
+     * Create parse tree buffer for code fragment
+     *
+     * @param object $parser    parser object
+     * @param string $data      content
+     */
+    public function __construct($parser, $data)
+    {
+        $this->parser = $parser;
+        $this->data = $data;
+    }
+
+    /**
+     * Return buffer content in parentheses
+     *
+     * @return string  content
+     */
+    public function to_smarty_php()
+    {
+        return sprintf("(%s)", $this->data);
+    }
+
+}
+
+/**
+ * Double quoted string inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_doublequoted extends _smarty_parsetree {
+
+    /**
+     * Create parse tree buffer for double quoted string subtrees
+     *
+     * @param object $parser    parser object
+     * @param _smarty_parsetree $subtree    parsetree buffer
+     */
+    public function __construct($parser, _smarty_parsetree $subtree)
+    {
+        $this->parser = $parser;
+        $this->subtrees[] = $subtree;
+        if ($subtree instanceof _smarty_tag) {
+            $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+        }
+    }
+
+    /**
+     * Append buffer to subtree
+     *
+     * @param _smarty_parsetree $subtree  parsetree buffer
+     */
+    public function append_subtree(_smarty_parsetree $subtree)
+    {
+        $last_subtree = count($this->subtrees) - 1;
+        if ($last_subtree >= 0 && $this->subtrees[$last_subtree] instanceof _smarty_tag && $this->subtrees[$last_subtree]->saved_block_nesting < $this->parser->block_nesting_level) {
+            if ($subtree instanceof _smarty_code) {
+                $this->subtrees[$last_subtree]->data .= '<?php echo ' . $subtree->data . ';?>';
+            } elseif ($subtree instanceof _smarty_dq_content) {
+                $this->subtrees[$last_subtree]->data .= '<?php echo "' . $subtree->data . '";?>';
+            } else {
+                $this->subtrees[$last_subtree]->data .= $subtree->data;
+            }
+        } else {
+            $this->subtrees[] = $subtree;
+        }
+        if ($subtree instanceof _smarty_tag) {
+            $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+        }
+    }
+
+    /**
+     * Merge subtree buffer content together
+     *
+     * @return string  compiled template code
+     */
+    public function to_smarty_php()
+    {
+        $code = '';
+        foreach ($this->subtrees as $subtree) {
+            if ($code !== "") {
+                $code .= ".";
+            }
+            if ($subtree instanceof _smarty_tag) {
+                $more_php = $subtree->assign_to_var();
+            } else {
+                $more_php = $subtree->to_smarty_php();
+            }
+
+            $code .= $more_php;
+
+            if (!$subtree instanceof _smarty_dq_content) {
+                $this->parser->compiler->has_variable_string = true;
+            }
+        }
+        return $code;
+    }
+
+}
+
+/**
+ * Raw chars as part of a double quoted string.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_dq_content extends _smarty_parsetree {
+
+
+    /**
+     * Create parse tree buffer with string content
+     *
+     * @param object $parser  parser object
+     * @param string $data    string section
+     */
+    public function __construct($parser, $data)
+    {
+        $this->parser = $parser;
+        $this->data = $data;
+    }
+
+    /**
+     * Return content as double quoted string
+     *
+     * @return string doubled quoted string
+     */
+    public function to_smarty_php()
+    {
+        return '"' . $this->data . '"';
+    }
+
+}
+
+/**
+ * Template element
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_template_buffer extends _smarty_parsetree {
+
+    /**
+     * Array of template elements
+     *
+     * @var array
+     */
+    public $subtrees = Array();
+
+    /**
+     * Create root of parse tree for template elements
+     *
+     * @param object $parser    parse object
+     */
+    public function __construct($parser)
+    {
+        $this->parser = $parser;
+    }
+
+    /**
+     * Append buffer to subtree
+     *
+     * @param _smarty_parsetree $subtree
+     */
+    public function append_subtree(_smarty_parsetree $subtree)
+    {
+        $this->subtrees[] = $subtree;
+    }
+
+    /**
+     * Sanitize and merge subtree buffers together
+     *
+     * @return string template code content
+     */
+    public function to_smarty_php()
+    {
+        $code = '';
+        for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
+            if ($key + 2 < $cnt) {
+                if ($this->subtrees[$key] instanceof _smarty_linebreak && $this->subtrees[$key + 1] instanceof _smarty_tag && $this->subtrees[$key + 1]->data == '' && $this->subtrees[$key + 2] instanceof _smarty_linebreak) {
+                    $key = $key + 1;
+                    continue;
+                }
+                if (substr($this->subtrees[$key]->data, -1) == '<' && $this->subtrees[$key + 1]->data == '' && substr($this->subtrees[$key + 2]->data, -1) == '?') {
+                    $key = $key + 2;
+                    continue;
+                }
+            }
+            if (substr($code, -1) == '<') {
+                $subtree = $this->subtrees[$key]->to_smarty_php();
+                if (substr($subtree, 0, 1) == '?') {
+                    $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>?' . substr($subtree, 1);
+                } elseif ($this->parser->asp_tags && substr($subtree, 0, 1) == '%') {
+                    $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>%' . substr($subtree, 1);
+                } else {
+                    $code .= $subtree;
+                }
+                continue;
+            }
+            if ($this->parser->asp_tags && substr($code, -1) == '%') {
+                $subtree = $this->subtrees[$key]->to_smarty_php();
+                if (substr($subtree, 0, 1) == '>') {
+                    $code = substr($code, 0, strlen($code) - 1) . '%<?php ?>>' . substr($subtree, 1);
+                } else {
+                    $code .= $subtree;
+                }
+                continue;
+            }
+            if (substr($code, -1) == '?') {
+                $subtree = $this->subtrees[$key]->to_smarty_php();
+                if (substr($subtree, 0, 1) == '>') {
+                    $code = substr($code, 0, strlen($code) - 1) . '?<?php ?>>' . substr($subtree, 1);
+                } else {
+                    $code .= $subtree;
+                }
+                continue;
+            }
+            $code .= $this->subtrees[$key]->to_smarty_php();
+        }
+        return $code;
+    }
+
+}
+
+/**
+ * template text
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_text extends _smarty_parsetree {
+
+
+    /**
+     * Create template text buffer
+     *
+     * @param object $parser    parser object
+     * @param string $data      text
+     */
+    public function __construct($parser, $data)
+    {
+        $this->parser = $parser;
+        $this->data = $data;
+    }
+
+    /**
+     * Return buffer content
+     *
+     * @return strint text
+     */
+    public function to_smarty_php()
+    {
+        return $this->data;
+    }
+
+}
+
+/**
+ * template linebreaks
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_linebreak extends _smarty_parsetree {
+
+    /**
+     * Create buffer with linebreak content
+     *
+     * @param object $parser    parser object
+     * @param string  $data     linebreak string
+     */
+    public function __construct($parser, $data)
+    {
+        $this->parser = $parser;
+        $this->data = $data;
+    }
+
+    /**
+     * Return linebrak
+     *
+     * @return string linebreak
+     */
+    public function to_smarty_php()
+    {
+        return $this->data;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_eval.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_eval.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_eval.php	(revision 345)
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Eval
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Eval
+ *
+ * Implements the strings as resource for Smarty template
+ *
+ * {@internal unlike string-resources the compiled state of eval-resources is NOT saved for subsequent access}}
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Eval extends Smarty_Resource_Recompiled {
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->uid = $source->filepath = sha1($source->name);
+        $source->timestamp = false;
+        $source->exists = true;
+    }
+
+    /**
+     * Load template's source from $resource_name into current template object
+     *
+     * @uses decode() to decode base64 and urlencoded template_resources
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        return $this->decode($source->name);
+    }
+    
+    /**
+     * decode base64 and urlencode
+     *
+     * @param string $string template_resource to decode
+     * @return string decoded template_resource
+     */
+    protected function decode($string)
+    {
+        // decode if specified
+        if (($pos = strpos($string, ':')) !== false) {
+            if (!strncmp($string, 'base64', 6)) {
+                return base64_decode(substr($string, 7));
+            } elseif (!strncmp($string, 'urlencode', 9)) {
+                return urldecode(substr($string, 10));
+            }
+        }
+        
+        return $string;
+    }
+    
+    /**
+     * modify resource_name according to resource handlers specifications
+     *
+     * @param Smarty $smarty        Smarty instance
+     * @param string $resource_name resource_name to make unique
+     * @return string unique resource name
+     */
+    protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
+    {
+        return get_class($this) . '#' .$this->decode($resource_name);
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    protected function getBasename(Smarty_Template_Source $source)
+    {
+        return '';
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_extends.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_extends.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_extends.php	(revision 345)
@@ -0,0 +1,148 @@
+<?php
+/**
+* Smarty Internal Plugin Resource Extends
+*
+* @package Smarty
+* @subpackage TemplateResources
+* @author Uwe Tews
+* @author Rodney Rehm
+*/
+
+/**
+* Smarty Internal Plugin Resource Extends
+*
+* Implements the file system as resource for Smarty which {extend}s a chain of template files templates
+*
+* @package Smarty
+* @subpackage TemplateResources
+*/
+class Smarty_Internal_Resource_Extends extends Smarty_Resource {
+
+    /**
+    * populate Source Object with meta data from Resource
+    *
+    * @param Smarty_Template_Source   $source    source object
+    * @param Smarty_Internal_Template $_template template object
+    */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $uid = '';
+        $sources = array();
+        $components = explode('|', $source->name);
+        $exists = true;
+        foreach ($components as $component) {
+            $s = Smarty_Resource::source(null, $source->smarty, $component);
+            if ($s->type == 'php') {
+                throw new SmartyException("Resource type {$s->type} cannot be used with the extends resource type");
+            }
+            $sources[$s->uid] = $s;
+            $uid .= $s->filepath;
+            if ($_template && $_template->smarty->compile_check) {
+                $exists == $exists && $s->exists;
+            }
+        }
+        $source->components = $sources;
+        $source->filepath = $s->filepath;
+        $source->uid = sha1($uid);
+        if ($_template && $_template->smarty->compile_check) {
+            $source->timestamp = $s->timestamp;
+            $source->exists = $exists;
+        }
+        // need the template at getContent()
+        $source->template = $_template;
+    }
+
+    /**
+    * populate Source Object with timestamp and exists from Resource
+    *
+    * @param Smarty_Template_Source $source source object
+    */
+    public function populateTimestamp(Smarty_Template_Source $source)
+    {
+        $source->exists = true;
+        foreach ($source->components as $s) {
+            $source->exists == $source->exists && $s->exists;
+        }
+        $source->timestamp = $s->timestamp;
+    }
+
+    /**
+    * Load template's source from files into current template object
+    *
+    * @param Smarty_Template_Source $source source object
+    * @return string template source
+    * @throws SmartyException if source cannot be loaded
+    */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        if (!$source->exists) {
+            throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+        }
+
+        $_rdl = preg_quote($source->smarty->right_delimiter);
+        $_ldl = preg_quote($source->smarty->left_delimiter);
+        $_components = array_reverse($source->components);
+        $_first = reset($_components);
+        $_last = end($_components);
+
+        foreach ($_components as $_component) {
+            // register dependency
+            if ($_component != $_first) {
+                $source->template->properties['file_dependency'][$_component->uid] = array($_component->filepath, $_component->timestamp, $_component->type);
+            }
+
+            // read content
+            $source->filepath = $_component->filepath;
+            $_content = $_component->content;
+
+            // extend sources
+            if ($_component != $_last) {
+                if (preg_match_all("!({$_ldl}block\s(.+?){$_rdl})!", $_content, $_open) !=
+                preg_match_all("!({$_ldl}/block{$_rdl})!", $_content, $_close)) {
+                    throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'");
+                }
+                preg_match_all("!{$_ldl}block\s(.+?){$_rdl}|{$_ldl}/block{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
+                $_result_count = count($_result[0]);
+                $_start = 0;
+                while ($_start+1 < $_result_count) {
+                    $_end = 0;
+                    $_level = 1;
+                    if (substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
+                        $_start++;
+                        continue;
+                    }
+                    while ($_level != 0) {
+                        $_end++;
+                        if (substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
+                            continue;
+                        }
+                        if (!strpos($_result[0][$_start + $_end][0], '/')) {
+                            $_level++;
+                        } else {
+                            $_level--;
+                        }
+                    }
+                    $_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
+                    Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath);
+                    $_start = $_start + $_end + 1;
+                }
+            } else {
+                return $_content;
+            }
+        }
+    }
+
+    /**
+    * Determine basename for compiled filename
+    *
+    * @param Smarty_Template_Source $source source object
+    * @return string resource's basename
+    */
+    public function getBasename(Smarty_Template_Source $source)
+    {
+        return str_replace(':', '.', basename($source->filepath));
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_file.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_file.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_file.php	(revision 345)
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource File
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource File
+ *
+ * Implements the file system as resource for Smarty templates
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_File extends Smarty_Resource {
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->filepath = $this->buildFilepath($source, $_template);
+
+        if ($source->filepath !== false) {
+            if (is_object($source->smarty->security_policy)) {
+                $source->smarty->security_policy->isTrustedResourceDir($source->filepath);
+            }
+
+            $source->uid = sha1($source->filepath);
+            if ($source->smarty->compile_check && !isset($source->timestamp)) {
+                $source->timestamp = @filemtime($source->filepath);
+                $source->exists = !!$source->timestamp;
+            }
+        }
+    }
+
+    /**
+     * populate Source Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Source $source source object
+     */
+    public function populateTimestamp(Smarty_Template_Source $source)
+    {
+        $source->timestamp = @filemtime($source->filepath);
+        $source->exists = !!$source->timestamp;
+    }
+
+    /**
+     * Load template's source from file into current template object
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        if ($source->timestamp) {
+            return file_get_contents($source->filepath);
+        }
+        if ($source instanceof Smarty_Config_Source) {
+            throw new SmartyException("Unable to read config {$source->type} '{$source->name}'");
+        }
+        throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    public function getBasename(Smarty_Template_Source $source)
+    {
+        $_file = $source->name;
+        if (($_pos = strpos($_file, ']')) !== false) {
+            $_file = substr($_file, $_pos + 1);
+        }
+        return basename($_file);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_php.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_php.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_php.php	(revision 345)
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Resource PHP
+ *
+ * Implements the file system as resource for PHP templates
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+class Smarty_Internal_Resource_PHP extends Smarty_Resource_Uncompiled {
+    /**
+     * container for short_open_tag directive's value before executing PHP templates
+     * @var string
+     */
+    protected $short_open_tag;
+
+    /**
+     * Create a new PHP Resource
+     *
+     */
+    public function __construct()
+    {
+        $this->short_open_tag = ini_get( 'short_open_tag' );
+    }
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source $source source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->filepath = $this->buildFilepath($source, $_template);
+
+        if ($source->filepath !== false) {
+            if (is_object($source->smarty->security_policy)) {
+                $source->smarty->security_policy->isTrustedResourceDir($source->filepath);
+            }
+
+            $source->uid = sha1($source->filepath);
+            if ($source->smarty->compile_check) {
+                $source->timestamp = @filemtime($source->filepath);
+                $source->exists = !!$source->timestamp;
+            }
+        }
+    }
+
+    /**
+     * populate Source Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return void
+     */
+    public function populateTimestamp(Smarty_Template_Source $source)
+    {
+        $source->timestamp = @filemtime($source->filepath);
+        $source->exists = !!$source->timestamp;
+    }
+
+    /**
+     * Load template's source from file into current template object
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        if ($source->timestamp) {
+            return '';
+        }
+        throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+    }
+
+    /**
+     * Render and output the template (without using the compiler)
+     *
+     * @param Smarty_Template_Source $source source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     * @throws SmartyException if template cannot be loaded or allow_php_templates is disabled
+     */
+    public function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template)
+    {
+        $_smarty_template = $_template;
+
+        if (!$source->smarty->allow_php_templates) {
+            throw new SmartyException("PHP templates are disabled");
+        }
+        if (!$source->exists) {
+            if ($_template->parent instanceof Smarty_Internal_Template) {
+                $parent_resource = " in '{$_template->parent->template_resource}'";
+            } else {
+                $parent_resource = '';
+            }
+            throw new SmartyException("Unable to load template {$source->type} '{$source->name}'{$parent_resource}");
+        }
+
+        // prepare variables
+        extract($_template->getTemplateVars());
+
+        // include PHP template with short open tags enabled
+        ini_set( 'short_open_tag', '1' );
+        include($source->filepath);
+        ini_set( 'short_open_tag', $this->short_open_tag );
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_registered.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_registered.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_registered.php	(revision 345)
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Registered
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Registered
+ *
+ * Implements the registered resource for Smarty template
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @deprecated
+ */
+class Smarty_Internal_Resource_Registered extends Smarty_Resource {
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->filepath = $source->type . ':' . $source->name;
+        $source->uid = sha1($source->filepath);
+        if ($source->smarty->compile_check) {
+            $source->timestamp = $this->getTemplateTimestamp($source);
+            $source->exists = !!$source->timestamp;
+        }
+    }
+
+    /**
+     * populate Source Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return void
+     */
+    public function populateTimestamp(Smarty_Template_Source $source)
+    {
+        $source->timestamp = $this->getTemplateTimestamp($source);
+        $source->exists = !!$source->timestamp;
+    }
+
+    /**
+     * Get timestamp (epoch) the template source was modified
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return integer|boolean timestamp (epoch) the template was modified, false if resources has no timestamp
+     */
+    public function getTemplateTimestamp(Smarty_Template_Source $source)
+    {
+        // return timestamp
+        $time_stamp = false;
+        call_user_func_array($source->smarty->registered_resources[$source->type][0][1], array($source->name, &$time_stamp, $source->smarty));
+        return is_numeric($time_stamp) ? (int) $time_stamp : $time_stamp;
+    }
+
+    /**
+     * Load template's source by invoking the registered callback into current template object
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        // return template string
+        $t = call_user_func_array($source->smarty->registered_resources[$source->type][0][0], array($source->name, &$source->content, $source->smarty));
+        if (is_bool($t) && !$t) {
+            throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+        }
+        return $source->content;
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    protected function getBasename(Smarty_Template_Source $source)
+    {
+        return basename($source->name);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_stream.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_stream.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_stream.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Stream
+ *
+ * Implements the streams as resource for Smarty template
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Stream
+ *
+ * Implements the streams as resource for Smarty template
+ *
+ * @link http://php.net/streams
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->filepath = str_replace(':', '://', $source->resource);
+        $source->uid = false;
+        $source->content = $this->getContent($source);
+        $source->timestamp = false;
+        $source->exists = !!$source->content;
+    }
+
+    /**
+     * Load template's source from stream into current template object
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        $t = '';
+        // the availability of the stream has already been checked in Smarty_Resource::fetch()
+        $fp = fopen($source->filepath, 'r+');
+        if ($fp) {
+            while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
+                $t .= $current_line;
+            }
+            fclose($fp);
+            return $t;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * modify resource_name according to resource handlers specifications
+     *
+     * @param Smarty $smarty        Smarty instance
+     * @param string $resource_name resource_name to make unique
+     * @return string unique resource name
+     */
+    protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
+    {
+        return get_class($this) . '#' . $resource_name;
+    }
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_string.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_string.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_resource_string.php	(revision 345)
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource String
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource String
+ *
+ * Implements the strings as resource for Smarty template
+ *
+ * {@internal unlike eval-resources the compiled state of string-resources is saved for subsequent access}}
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_String extends Smarty_Resource {
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->uid = $source->filepath = sha1($source->name);
+        $source->timestamp = 0;
+        $source->exists = true;
+    }
+
+    /**
+     * Load template's source from $resource_name into current template object
+     *
+     * @uses decode() to decode base64 and urlencoded template_resources
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        return $this->decode($source->name);
+    }
+    
+    /**
+     * decode base64 and urlencode
+     *
+     * @param string $string template_resource to decode
+     * @return string decoded template_resource
+     */
+    protected function decode($string)
+    {
+        // decode if specified
+        if (($pos = strpos($string, ':')) !== false) {
+            if (!strncmp($string, 'base64', 6)) {
+                return base64_decode(substr($string, 7));
+            } elseif (!strncmp($string, 'urlencode', 9)) {
+                return urldecode(substr($string, 10));
+            }
+        }
+        
+        return $string;
+    }
+    
+    /**
+     * modify resource_name according to resource handlers specifications
+     *
+     * @param Smarty $smarty        Smarty instance
+     * @param string $resource_name resource_name to make unique
+     * @return string unique resource name
+     */
+    protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
+    {
+        return get_class($this) . '#' .$this->decode($resource_name);
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * Always returns an empty string.
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    protected function getBasename(Smarty_Template_Source $source)
+    {
+        return '';
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_smartytemplatecompiler.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_smartytemplatecompiler.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_smartytemplatecompiler.php	(revision 345)
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Smarty Internal Plugin Smarty Template Compiler Base
+ *
+ * This file contains the basic classes and methodes for compiling Smarty templates with lexer/parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * @ignore
+ */
+include ("smarty_internal_parsetree.php");
+
+/**
+ * Class SmartyTemplateCompiler
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase {
+
+    /**
+     * Lexer class name
+     *
+     * @var string
+     */
+    public $lexer_class;
+
+    /**
+     * Parser class name
+     *
+     * @var string
+     */
+    public $parser_class;
+
+    /**
+     * Lexer object
+     *
+     * @var object
+     */
+    public $lex;
+
+    /**
+     * Parser object
+     *
+     * @var object
+     */
+    public $parser;
+
+    /**
+     * Smarty object
+     *
+     * @var object
+     */
+    public $smarty;
+
+    /**
+     * array of vars which can be compiled in local scope
+     *
+     * @var array
+     */
+    public $local_var = array();
+
+    /**
+     * Initialize compiler
+     *
+     * @param string $lexer_class  class name
+     * @param string $parser_class class name
+     * @param Smarty $smarty       global instance
+     */
+    public function __construct($lexer_class, $parser_class, $smarty)
+    {
+        $this->smarty = $smarty;
+        parent::__construct();
+        // get required plugins
+        $this->lexer_class = $lexer_class;
+        $this->parser_class = $parser_class;
+    }
+
+    /**
+     * Methode to compile a Smarty template
+     *
+     * @param  mixed $_content template source
+     * @return bool true if compiling succeeded, false if it failed
+     */
+    protected function doCompile($_content)
+    {
+        /* here is where the compiling takes place. Smarty
+          tags in the templates are replaces with PHP code,
+          then written to compiled files. */
+        // init the lexer/parser to compile the template
+        $this->lex = new $this->lexer_class($_content, $this);
+        $this->parser = new $this->parser_class($this->lex, $this);
+        if ($this->smarty->_parserdebug)
+            $this->parser->PrintTrace();
+        // get tokens from lexer and parse them
+        while ($this->lex->yylex() && !$this->abort_and_recompile) {
+            if ($this->smarty->_parserdebug) {
+                echo "<pre>Line {$this->lex->line} Parsing  {$this->parser->yyTokenName[$this->lex->token]} Token " .
+                    htmlentities($this->lex->value) . "</pre>";
+            }
+            $this->parser->doParse($this->lex->token, $this->lex->value);
+        }
+
+        if ($this->abort_and_recompile) {
+            // exit here on abort
+            return false;
+        }
+        // finish parsing process
+        $this->parser->doParse(0, 0);
+        // check for unclosed tags
+        if (count($this->_tag_stack) > 0) {
+            // get stacked info
+            list($openTag, $_data) = array_pop($this->_tag_stack);
+            $this->trigger_template_error("unclosed {" . $openTag . "} tag");
+        }
+        // return compiled code
+        // return str_replace(array("? >\n<?php","? ><?php"), array('',''), $this->parser->retvalue);
+        return $this->parser->retvalue;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_template.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_template.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_template.php	(revision 345)
@@ -0,0 +1,684 @@
+<?php
+/**
+ * Smarty Internal Plugin Template
+ *
+ * This file contains the Smarty template engine
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Main class with template data structures and methods
+ *
+ * @package Smarty
+ * @subpackage Template
+ *
+ * @property Smarty_Template_Source   $source
+ * @property Smarty_Template_Compiled $compiled
+ * @property Smarty_Template_Cached   $cached
+ */
+class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
+
+    /**
+     * cache_id
+     * @var string
+     */
+    public $cache_id = null;
+    /**
+     * $compile_id
+     * @var string
+     */
+    public $compile_id = null;
+    /**
+     * caching enabled
+     * @var boolean
+     */
+    public $caching = null;
+    /**
+     * cache lifetime in seconds
+     * @var integer
+     */
+    public $cache_lifetime = null;
+    /**
+     * Template resource
+     * @var string
+     */
+    public $template_resource = null;
+    /**
+     * flag if compiled template is invalid and must be (re)compiled
+     * @var bool
+     */
+    public $mustCompile = null;
+    /**
+     * flag if template does contain nocache code sections
+     * @var bool
+     */
+    public $has_nocache_code = false;
+    /**
+     * special compiled and cached template properties
+     * @var array
+     */
+    public $properties = array('file_dependency' => array(),
+        'nocache_hash' => '',
+        'function' => array());
+    /**
+     * required plugins
+     * @var array
+     */
+    public $required_plugins = array('compiled' => array(), 'nocache' => array());
+    /**
+     * Global smarty instance
+     * @var Smarty
+     */
+    public $smarty = null;
+    /**
+     * blocks for template inheritance
+     * @var array
+     */
+    public $block_data = array();
+    /**
+     * variable filters
+     * @var array
+     */
+    public $variable_filters = array();
+    /**
+     * optional log of tag/attributes
+     * @var array
+     */
+    public $used_tags = array();
+    /**
+     * internal flag to allow relative path in child template blocks
+     * @var bool
+     */
+    public $allow_relative_path = false;
+    /**
+     * internal capture runtime stack
+     * @var array
+     */
+    public $_capture_stack = array(0 => array());
+
+    /**
+     * Create template data object
+     *
+     * Some of the global Smarty settings copied to template scope
+     * It load the required template resources and cacher plugins
+     *
+     * @param string                   $template_resource template resource string
+     * @param Smarty                   $smarty            Smarty instance
+     * @param Smarty_Internal_Template $_parent           back pointer to parent object with variables or null
+     * @param mixed                    $_cache_id cache   id or null
+     * @param mixed                    $_compile_id       compile id or null
+     * @param bool                     $_caching          use caching?
+     * @param int                      $_cache_lifetime   cache life-time in seconds
+     */
+    public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null)
+    {
+        $this->smarty = &$smarty;
+        // Smarty parameter
+        $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
+        $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
+        $this->caching = $_caching === null ? $this->smarty->caching : $_caching;
+        if ($this->caching === true)
+            $this->caching = Smarty::CACHING_LIFETIME_CURRENT;
+        $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
+        $this->parent = $_parent;
+        // Template resource
+        $this->template_resource = $template_resource;
+        // copy block data of template inheritance
+        if ($this->parent instanceof Smarty_Internal_Template) {
+            $this->block_data = $this->parent->block_data;
+        }
+    }
+
+    /**
+     * Returns if the current template must be compiled by the Smarty compiler
+     *
+     * It does compare the timestamps of template source and the compiled templates and checks the force compile configuration
+     *
+     * @return boolean true if the template must be compiled
+     */
+    public function mustCompile()
+    {
+        if (!$this->source->exists) {
+            if ($this->parent instanceof Smarty_Internal_Template) {
+                $parent_resource = " in '$this->parent->template_resource}'";
+            } else {
+                $parent_resource = '';
+            }
+            throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
+        }
+        if ($this->mustCompile === null) {
+            $this->mustCompile = (!$this->source->uncompiled && ($this->smarty->force_compile || $this->source->recompiled || $this->compiled->timestamp === false ||
+                    ($this->smarty->compile_check && $this->compiled->timestamp < $this->source->timestamp)));
+        }
+        return $this->mustCompile;
+    }
+
+    /**
+     * Compiles the template
+     *
+     * If the template is not evaluated the compiled template is saved on disk
+     */
+    public function compileTemplateSource()
+    {
+        if (!$this->source->recompiled) {
+            $this->properties['file_dependency'] = array();
+            if ($this->source->components) {
+                // uses real resource for file dependency
+                $source = end($this->source->components);
+                $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type);
+            } else {
+                $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
+            }
+        }
+        if ($this->smarty->debugging) {
+            Smarty_Internal_Debug::start_compile($this);
+        }
+        // compile locking
+        if ($this->smarty->compile_locking && !$this->source->recompiled) {
+            if ($saved_timestamp = $this->compiled->timestamp) {
+                @touch($this->compiled->filepath);
+            }
+        }
+        // call compiler
+        try {
+            $code = $this->compiler->compileTemplate($this);
+        } catch (Exception $e) {
+            // restore old timestamp in case of error
+            if ($this->smarty->compile_locking && !$this->source->recompiled && $saved_timestamp) {
+                touch($this->compiled->filepath, $saved_timestamp);
+            }
+            throw $e;
+        }
+        // compiling succeded
+        if (!$this->source->recompiled && $this->compiler->write_compiled_code) {
+            // write compiled template
+            $_filepath = $this->compiled->filepath;
+            if ($_filepath === false)
+                throw new SmartyException('getCompiledFilepath() did not return a destination to save the compiled template to');
+            Smarty_Internal_Write_File::writeFile($_filepath, $code, $this->smarty);
+            $this->compiled->exists = true;
+            $this->compiled->isCompiled = true;
+        }
+        if ($this->smarty->debugging) {
+            Smarty_Internal_Debug::end_compile($this);
+        }
+        // release compiler object to free memory
+        unset($this->compiler);
+    }
+
+    /**
+     * Writes the cached template output
+     *
+     * @return bool
+     */
+    public function writeCachedContent($content)
+    {
+        if ($this->source->recompiled || !($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED)) {
+            // don't write cache file
+            return false;
+        }
+        $this->properties['cache_lifetime'] = $this->cache_lifetime;
+        $this->properties['unifunc'] = 'content_' . uniqid('', false);
+        $content = $this->createTemplateCodeFrame($content, true);
+        $_smarty_tpl = $this;
+        eval("?>" . $content);
+        $this->cached->valid = true;
+        $this->cached->processed = true;
+        return $this->cached->write($this, $content);
+    }
+
+    /**
+     * Template code runtime function to get subtemplate content
+     *
+     * @param string  $template       the resource handle of the template file
+     * @param mixed   $cache_id       cache id to be used with this template
+     * @param mixed   $compile_id     compile id to be used with this template
+     * @param integer $caching        cache mode
+     * @param integer $cache_lifetime life time of cache data
+     * @param array   $vars optional  variables to assign
+     * @param int     $parent_scope   scope in which {include} should execute
+     * @returns string template content
+     */
+    public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope)
+    {
+        // already in template cache?
+        if ($this->smarty->allow_ambiguous_resources) {
+            $_templateId = Smarty_Resource::getUniqueTemplateName($this->smarty, $template) . $cache_id . $compile_id;
+        } else {
+            $_templateId = $this->smarty->joined_template_dir . '#' . $template . $cache_id . $compile_id;
+        }
+
+        if (isset($_templateId[150])) {
+            $_templateId = sha1($_templateId);
+        }
+        if (isset($this->smarty->template_objects[$_templateId])) {
+            // clone cached template object because of possible recursive call
+            $tpl = clone $this->smarty->template_objects[$_templateId];
+            $tpl->parent = $this;
+            $tpl->caching = $caching;
+            $tpl->cache_lifetime = $cache_lifetime;
+        } else {
+            $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
+        }
+        // get variables from calling scope
+        if ($parent_scope == Smarty::SCOPE_LOCAL) {
+            $tpl->tpl_vars = $this->tpl_vars;
+        } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
+            $tpl->tpl_vars = &$this->tpl_vars;
+        } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
+            $tpl->tpl_vars = &Smarty::$global_tpl_vars;
+        } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
+            $tpl->tpl_vars = &$this->tpl_vars;
+        } else {
+            $tpl->tpl_vars = &$scope_ptr->tpl_vars;
+        }
+        $tpl->config_vars = $this->config_vars;
+        if (!empty($data)) {
+            // set up variable values
+            foreach ($data as $_key => $_val) {
+                $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
+            }
+        }
+        return $tpl->fetch(null, null, null, null, false, false, true);
+    }
+
+    /**
+     * Template code runtime function to set up an inline subtemplate
+     *
+     * @param string  $template       the resource handle of the template file
+     * @param mixed   $cache_id       cache id to be used with this template
+     * @param mixed   $compile_id     compile id to be used with this template
+     * @param integer $caching        cache mode
+     * @param integer $cache_lifetime life time of cache data
+     * @param array   $vars optional  variables to assign
+     * @param int     $parent_scope   scope in which {include} should execute
+     * @param string  $hash           nocache hash code
+     * @returns string template content
+     */
+    public function setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash)
+    {
+        $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
+        $tpl->properties['nocache_hash']  = $hash;
+        // get variables from calling scope
+        if ($parent_scope == Smarty::SCOPE_LOCAL ) {
+            $tpl->tpl_vars = $this->tpl_vars;
+        } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
+            $tpl->tpl_vars = &$this->tpl_vars;
+        } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
+            $tpl->tpl_vars = &Smarty::$global_tpl_vars;
+        } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
+            $tpl->tpl_vars = &$this->tpl_vars;
+        } else {
+            $tpl->tpl_vars = &$scope_ptr->tpl_vars;
+        }
+        $tpl->config_vars = $this->config_vars;
+        if (!empty($data)) {
+            // set up variable values
+            foreach ($data as $_key => $_val) {
+                $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
+            }
+        }
+        return $tpl;
+    }
+
+
+    /**
+     * Create code frame for compiled and cached templates
+     *
+     * @param string $content   optional template content
+     * @param bool   $cache     flag for cache file
+     * @return string
+     */
+    public function createTemplateCodeFrame($content = '', $cache = false)
+    {
+        $plugins_string = '';
+        // include code for plugins
+        if (!$cache) {
+            if (!empty($this->required_plugins['compiled'])) {
+                $plugins_string = '<?php ';
+                foreach ($this->required_plugins['compiled'] as $tmp) {
+                    foreach ($tmp as $data) {
+                        $file = addslashes($data['file']);
+                        $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n";
+                    }
+                }
+                $plugins_string .= '?>';
+            }
+            if (!empty($this->required_plugins['nocache'])) {
+                $this->has_nocache_code = true;
+                $plugins_string .= "<?php echo '/*%%SmartyNocache:{$this->properties['nocache_hash']}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
+                foreach ($this->required_plugins['nocache'] as $tmp) {
+                    foreach ($tmp as $data) {
+                        $file = addslashes($data['file']);
+                        $plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n");
+                    }
+                }
+                $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
+            }
+        }
+        // build property code
+        $this->properties['has_nocache_code'] = $this->has_nocache_code;
+        $output = '';
+        if (!$this->source->recompiled) {
+            $output = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/";
+            if ($this->smarty->direct_access_security) {
+                $output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
+            }
+        }
+        if ($cache) {
+            // remove compiled code of{function} definition
+            unset($this->properties['function']);
+            if (!empty($this->smarty->template_functions)) {
+                // copy code of {function} tags called in nocache mode
+                foreach ($this->smarty->template_functions as $name => $function_data) {
+                    if (isset($function_data['called_nocache'])) {
+                        foreach ($function_data['called_functions'] as $func_name) {
+                            $this->smarty->template_functions[$func_name]['called_nocache'] = true;
+                        }
+                    }
+                }
+                 foreach ($this->smarty->template_functions as $name => $function_data) {
+                    if (isset($function_data['called_nocache'])) {
+                        unset($function_data['called_nocache'], $function_data['called_functions'], $this->smarty->template_functions[$name]['called_nocache']);
+                        $this->properties['function'][$name] = $function_data;
+                    }
+                }
+            }
+        }
+        $this->properties['version'] = Smarty::SMARTY_VERSION;
+        if (!isset($this->properties['unifunc'])) {
+            $this->properties['unifunc'] = 'content_' . uniqid('', false);
+        }
+        if (!$this->source->recompiled) {
+            $output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n";
+        }
+        if (!$this->source->recompiled) {
+            $output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>';
+        }
+        $output .= $plugins_string;
+        $output .= $content;
+        if (!$this->source->recompiled) {
+            $output .= '<?php }} ?>';
+        }
+        return $output;
+    }
+
+    /**
+     * This function is executed automatically when a compiled or cached template file is included
+     *
+     * - Decode saved properties from compiled template and cache files
+     * - Check if compiled or cache file is valid
+     *
+     * @param array $properties     special template properties
+     * @param bool  $cache          flag if called from cache file
+     * @return bool                 flag if compiled or cache file is valid
+     */
+    public function decodeProperties($properties, $cache = false)
+    {
+        $this->has_nocache_code = $properties['has_nocache_code'];
+        $this->properties['nocache_hash'] = $properties['nocache_hash'];
+        if (isset($properties['cache_lifetime'])) {
+            $this->properties['cache_lifetime'] = $properties['cache_lifetime'];
+        }
+        if (isset($properties['file_dependency'])) {
+            $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
+        }
+        if (!empty($properties['function'])) {
+            $this->properties['function'] = array_merge($this->properties['function'], $properties['function']);
+            $this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']);
+        }
+        $this->properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
+        $this->properties['unifunc'] = $properties['unifunc'];
+        // check file dependencies at compiled code
+        $is_valid = true;
+        if ($this->properties['version'] != Smarty::SMARTY_VERSION) {
+            $is_valid = false;
+        } else if (((!$cache && $this->smarty->compile_check && empty($this->compiled->_properties) && !$this->compiled->isCompiled) || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($this->properties['file_dependency'])) {
+            foreach ($this->properties['file_dependency'] as $_file_to_check) {
+                if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
+                    if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) {
+                        // do not recheck current template
+                        $mtime = $this->source->timestamp;
+                    } else {
+                        // file and php types can be checked without loading the respective resource handlers
+                        $mtime = filemtime($_file_to_check[0]);
+                    }
+                } elseif ($_file_to_check[2] == 'string') {
+                    continue;
+                } else {
+                    $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
+                    $mtime = $source->timestamp;
+                }
+                if ($mtime > $_file_to_check[1]) {
+                    $is_valid = false;
+                    break;
+                }
+            }
+        }
+        if ($cache) {
+            $this->cached->valid = $is_valid;
+        } else {
+            $this->mustCompile = !$is_valid;
+        }
+        // store data in reusable Smarty_Template_Compiled
+        if (!$cache) {
+            $this->compiled->_properties = $properties;
+        }
+        return $is_valid;
+    }
+
+    /**
+     * Template code runtime function to create a local Smarty variable for array assignments
+     *
+     * @param string $tpl_var   tempate variable name
+     * @param bool   $nocache   cache mode of variable
+     * @param int    $scope     scope of variable
+     */
+    public function createLocalArrayVariable($tpl_var, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
+    {
+        if (!isset($this->tpl_vars[$tpl_var])) {
+            $this->tpl_vars[$tpl_var] = new Smarty_variable(array(), $nocache, $scope);
+        } else {
+            $this->tpl_vars[$tpl_var] = clone $this->tpl_vars[$tpl_var];
+            if ($scope != Smarty::SCOPE_LOCAL) {
+                $this->tpl_vars[$tpl_var]->scope = $scope;
+            }
+            if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
+                settype($this->tpl_vars[$tpl_var]->value, 'array');
+            }
+        }
+    }
+
+    /**
+     * Template code runtime function to get pointer to template variable array of requested scope
+     *
+     * @param int $scope    requested variable scope
+     * @return array        array of template variables
+     */
+    public function &getScope($scope)
+    {
+        if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
+            return $this->parent->tpl_vars;
+        } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
+            $ptr = $this->parent;
+            while (!empty($ptr->parent)) {
+                $ptr = $ptr->parent;
+            }
+            return $ptr->tpl_vars;
+        } elseif ($scope == Smarty::SCOPE_GLOBAL) {
+            return Smarty::$global_tpl_vars;
+        }
+        $null = null;
+        return $null;
+    }
+
+    /**
+     * Get parent or root of template parent chain
+     *
+     * @param int $scope    pqrent or root scope
+     * @return mixed object
+     */
+    public function getScopePointer($scope)
+    {
+        if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
+            return $this->parent;
+        } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
+            $ptr = $this->parent;
+            while (!empty($ptr->parent)) {
+                $ptr = $ptr->parent;
+            }
+            return $ptr;
+        }
+        return null;
+    }
+
+    /**
+     * [util function] counts an array, arrayaccess/traversable or PDOStatement object
+     *
+     * @param mixed $value
+     * @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0 for empty elements
+     */
+    public function _count($value)
+    {
+        if (is_array($value) === true || $value instanceof Countable) {
+            return count($value);
+        } elseif ($value instanceof IteratorAggregate) {
+            // Note: getIterator() returns a Traversable, not an Iterator
+            // thus rewind() and valid() methods may not be present
+            return iterator_count($value->getIterator());
+        } elseif ($value instanceof Iterator) {
+            return iterator_count($value);
+        } elseif ($value instanceof PDOStatement) {
+            return $value->rowCount();
+        } elseif ($value instanceof Traversable) {
+            return iterator_count($value);
+        } elseif ($value instanceof ArrayAccess) {
+            if ($value->offsetExists(0)) {
+                return 1;
+            }
+        } elseif (is_object($value)) {
+            return count($value);
+        }
+        return 0;
+    }
+
+    /**
+     * runtime error not matching capture tags
+     *
+     */
+    public function capture_error()
+    {
+        throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
+    }
+
+    /**
+    * Empty cache for this template
+    *
+    * @param integer $exp_time      expiration time
+    * @return integer number of cache files deleted
+    */
+    public function clearCache($exp_time=null)
+    {
+        Smarty_CacheResource::invalidLoadedCache($this->smarty);
+        return $this->cached->handler->clear($this->smarty, $this->template_name, $this->cache_id, $this->compile_id, $exp_time);
+    }
+
+     /**
+     * set Smarty property in template context
+     *
+     * @param string $property_name property name
+     * @param mixed  $value         value
+     */
+    public function __set($property_name, $value)
+    {
+        switch ($property_name) {
+            case 'source':
+            case 'compiled':
+            case 'cached':
+            case 'compiler':
+                $this->$property_name = $value;
+                return;
+
+            // FIXME: routing of template -> smarty attributes
+            default:
+                if (property_exists($this->smarty, $property_name)) {
+                    $this->smarty->$property_name = $value;
+                    return;
+                }
+        }
+
+        throw new SmartyException("invalid template property '$property_name'.");
+    }
+
+    /**
+     * get Smarty property in template context
+     *
+     * @param string $property_name property name
+     */
+    public function __get($property_name)
+    {
+        switch ($property_name) {
+            case 'source':
+                if (empty($this->template_resource)) {
+                    throw new SmartyException("Unable to parse resource name \"{$this->template_resource}\"");
+                }
+                $this->source = Smarty_Resource::source($this);
+                // cache template object under a unique ID
+                // do not cache eval resources
+                if ($this->source->type != 'eval') {
+                    if ($this->smarty->allow_ambiguous_resources) {
+                        $_templateId = $this->source->unique_resource . $this->cache_id . $this->compile_id;
+                    } else {
+                        $_templateId = $this->smarty->joined_template_dir . '#' . $this->template_resource . $this->cache_id . $this->compile_id;
+                    }
+
+                    if (isset($_templateId[150])) {
+                        $_templateId = sha1($_templateId);
+                    }
+                    $this->smarty->template_objects[$_templateId] = $this;
+                }
+                return $this->source;
+
+            case 'compiled':
+                $this->compiled = $this->source->getCompiled($this);
+                return $this->compiled;
+
+            case 'cached':
+                if (!class_exists('Smarty_Template_Cached')) {
+                    include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
+                }
+                $this->cached = new Smarty_Template_Cached($this);
+                return $this->cached;
+
+            case 'compiler':
+                $this->smarty->loadPlugin($this->source->compiler_class);
+                $this->compiler = new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty);
+                return $this->compiler;
+
+            // FIXME: routing of template -> smarty attributes
+            default:
+                if (property_exists($this->smarty, $property_name)) {
+                    return $this->smarty->$property_name;
+                }
+        }
+
+        throw new SmartyException("template property '$property_name' does not exist.");
+    }
+
+    /**
+     * Template data object destrutor
+     *
+     */
+    public function __destruct()
+    {
+        if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
+            $this->cached->handler->releaseLock($this->smarty, $this->cached);
+        }
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatebase.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatebase.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatebase.php	(revision 345)
@@ -0,0 +1,811 @@
+<?php
+/**
+ * Smarty Internal Plugin Smarty Template  Base
+ *
+ * This file contains the basic shared methodes for template handling
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Class with shared template methodes
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
+
+    /**
+     * fetches a rendered Smarty template
+     *
+     * @param string $template          the resource handle of the template file or template object
+     * @param mixed  $cache_id          cache id to be used with this template
+     * @param mixed  $compile_id        compile id to be used with this template
+     * @param object $parent            next higher level of Smarty variables
+     * @param bool   $display           true: display, false: fetch
+     * @param bool   $merge_tpl_vars    if true parent template variables merged in to local scope
+     * @param bool   $no_output_filter  if true do not run output filter
+     * @return string rendered template output
+     */
+    public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
+    {
+        if ($template === null && $this instanceof $this->template_class) {
+            $template = $this;
+        }
+        if (!empty($cache_id) && is_object($cache_id)) {
+            $parent = $cache_id;
+            $cache_id = null;
+        }
+        if ($parent === null && ($this instanceof Smarty || is_string($template))) {
+            $parent = $this;
+        }
+        // create template object if necessary
+        $_template = ($template instanceof $this->template_class)
+        ? $template
+        : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
+        // if called by Smarty object make sure we use current caching status
+        if ($this instanceof Smarty) {
+            $_template->caching = $this->caching;
+        }
+        // merge all variable scopes into template
+        if ($merge_tpl_vars) {
+            // save local variables
+            $save_tpl_vars = $_template->tpl_vars;
+            $save_config_vars = $_template->config_vars;
+            $ptr_array = array($_template);
+            $ptr = $_template;
+            while (isset($ptr->parent)) {
+                $ptr_array[] = $ptr = $ptr->parent;
+            }
+            $ptr_array = array_reverse($ptr_array);
+            $parent_ptr = reset($ptr_array);
+            $tpl_vars = $parent_ptr->tpl_vars;
+            $config_vars = $parent_ptr->config_vars;
+            while ($parent_ptr = next($ptr_array)) {
+                if (!empty($parent_ptr->tpl_vars)) {
+                    $tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars);
+                }
+                if (!empty($parent_ptr->config_vars)) {
+                    $config_vars = array_merge($config_vars, $parent_ptr->config_vars);
+                }
+            }
+            if (!empty(Smarty::$global_tpl_vars)) {
+                $tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars);
+            }
+            $_template->tpl_vars = $tpl_vars;
+            $_template->config_vars = $config_vars;
+        }
+        // dummy local smarty variable
+        if (!isset($_template->tpl_vars['smarty'])) {
+            $_template->tpl_vars['smarty'] = new Smarty_Variable;
+        }
+        if (isset($this->smarty->error_reporting)) {
+            $_smarty_old_error_level = error_reporting($this->smarty->error_reporting);
+        }
+        // check URL debugging control
+        if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
+            if (isset($_SERVER['QUERY_STRING'])) {
+                $_query_string = $_SERVER['QUERY_STRING'];
+            } else {
+                $_query_string = '';
+            }
+            if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) {
+                if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) {
+                    // enable debugging for this browser session
+                    setcookie('SMARTY_DEBUG', true);
+                    $this->smarty->debugging = true;
+                } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) {
+                    // disable debugging for this browser session
+                    setcookie('SMARTY_DEBUG', false);
+                    $this->smarty->debugging = false;
+                } else {
+                    // enable debugging for this page
+                    $this->smarty->debugging = true;
+                }
+            } else {
+                if (isset($_COOKIE['SMARTY_DEBUG'])) {
+                    $this->smarty->debugging = true;
+                }
+            }
+        }
+        // must reset merge template date
+        $_template->smarty->merged_templates_func = array();
+        // get rendered template
+        // disable caching for evaluated code
+        if ($_template->source->recompiled) {
+            $_template->caching = false;
+        }
+        // checks if template exists
+        if (!$_template->source->exists) {
+            if ($_template->parent instanceof Smarty_Internal_Template) {
+                $parent_resource = " in '{$_template->parent->template_resource}'";
+            } else {
+                $parent_resource = '';
+            }
+            throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}");
+        }
+        // read from cache or render
+        if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) {
+            // render template (not loaded and not in cache)
+            if (!$_template->source->uncompiled) {
+                $_smarty_tpl = $_template;
+                if ($_template->source->recompiled) {
+                    if ($this->smarty->debugging) {
+                        Smarty_Internal_Debug::start_compile($_template);
+                    }
+                    $code = $_template->compiler->compileTemplate($_template);
+                    if ($this->smarty->debugging) {
+                        Smarty_Internal_Debug::end_compile($_template);
+                    }
+                    if ($this->smarty->debugging) {
+                        Smarty_Internal_Debug::start_render($_template);
+                    }
+                    try {
+                        ob_start();
+                        eval("?>" . $code);
+                        unset($code);
+                    } catch (Exception $e) {
+                        ob_get_clean();
+                        throw $e;
+                    }
+                } else {
+                    if (!$_template->compiled->exists || ($_template->smarty->force_compile && !$_template->compiled->isCompiled)) {
+                        $_template->compileTemplateSource();
+                    }
+                    if ($this->smarty->debugging) {
+                        Smarty_Internal_Debug::start_render($_template);
+                    }
+                    if (!$_template->compiled->loaded) {
+                        include($_template->compiled->filepath);
+                        if ($_template->mustCompile) {
+                            // recompile and load again
+                            $_template->compileTemplateSource();
+                            include($_template->compiled->filepath);
+                        }
+                        $_template->compiled->loaded = true;
+                    } else {
+                        $_template->decodeProperties($_template->compiled->_properties, false);
+                    }
+                    try {
+                        ob_start();
+                        if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) {
+                            throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'");
+                        }
+                        array_unshift($_template->_capture_stack,array());
+                        //
+                        // render compiled template
+                        //
+                        $_template->properties['unifunc']($_template);
+                        // any unclosed {capture} tags ?
+                        if (isset($_template->_capture_stack[0][0])) {
+                            $_template->capture_error();
+                        }
+                        array_shift($_template->_capture_stack);
+                    } catch (Exception $e) {
+                        ob_get_clean();
+                        throw $e;
+                    }
+                }
+            } else {
+                if ($_template->source->uncompiled) {
+                    if ($this->smarty->debugging) {
+                        Smarty_Internal_Debug::start_render($_template);
+                    }
+                    try {
+                        ob_start();
+                        $_template->source->renderUncompiled($_template);
+                    } catch (Exception $e) {
+                        ob_get_clean();
+                        throw $e;
+                    }
+                } else {
+                    throw new SmartyException("Resource '$_template->source->type' must have 'renderUncompiled' method");
+                }
+            }
+            $_output = ob_get_clean();
+            if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) {
+                $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
+            }
+            if ($_template->parent instanceof Smarty_Internal_Template) {
+                $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']);
+                foreach ($_template->required_plugins as $code => $tmp1) {
+                    foreach ($tmp1 as $name => $tmp) {
+                        foreach ($tmp as $type => $data) {
+                            $_template->parent->required_plugins[$code][$name][$type] = $data;
+                        }
+                    }
+                }
+            }
+            if ($this->smarty->debugging) {
+                Smarty_Internal_Debug::end_render($_template);
+            }
+            // write to cache when nessecary
+            if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) {
+                if ($this->smarty->debugging) {
+                    Smarty_Internal_Debug::start_cache($_template);
+                }
+                $_template->properties['has_nocache_code'] = false;
+                // get text between non-cached items
+                $cache_split = preg_split("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output);
+                // get non-cached items
+                preg_match_all("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output, $cache_parts);
+                $output = '';
+                // loop over items, stitch back together
+                foreach ($cache_split as $curr_idx => $curr_split) {
+                    // escape PHP tags in template content
+                    $output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php echo \'$1\'; ?>', $curr_split);
+                    if (isset($cache_parts[0][$curr_idx])) {
+                        $_template->properties['has_nocache_code'] = true;
+                        // remove nocache tags from cache output
+                        $output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
+                    }
+                }
+                if (!$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
+                    $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
+                }
+                // rendering (must be done before writing cache file because of {function} nocache handling)
+                $_smarty_tpl = $_template;
+                try {
+                    ob_start();
+                    eval("?>" . $output);
+                    $_output = ob_get_clean();
+                } catch (Exception $e) {
+                    ob_get_clean();
+                    throw $e;
+                }
+                // write cache file content
+                $_template->writeCachedContent($output);
+                if ($this->smarty->debugging) {
+                    Smarty_Internal_Debug::end_cache($_template);
+                }
+            } else {
+                // var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output);
+                if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) {
+                    // replace nocache_hash
+                    $_output = preg_replace("/{$_template->properties['nocache_hash']}/", $_template->parent->properties['nocache_hash'], $_output);
+                    $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code;
+                }
+            }
+        } else {
+            if ($this->smarty->debugging) {
+                Smarty_Internal_Debug::start_cache($_template);
+            }
+            try {
+                ob_start();
+                array_unshift($_template->_capture_stack,array());
+                //
+                // render cached template
+                //
+                $_template->properties['unifunc']($_template);
+                // any unclosed {capture} tags ?
+                if (isset($_template->_capture_stack[0][0])) {
+                    $_template->capture_error();
+                }
+                array_shift($_template->_capture_stack);
+                $_output = ob_get_clean();
+            } catch (Exception $e) {
+                ob_get_clean();
+                throw $e;
+            }
+            if ($this->smarty->debugging) {
+                Smarty_Internal_Debug::end_cache($_template);
+            }
+        }
+        if ((!$this->caching || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
+            $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template);
+        }
+        if (isset($this->error_reporting)) {
+            error_reporting($_smarty_old_error_level);
+        }
+        // display or fetch
+        if ($display) {
+            if ($this->caching && $this->cache_modified_check) {
+                $_isCached = $_template->isCached() && !$_template->has_nocache_code;
+                $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+                if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) {
+                    switch (PHP_SAPI) {
+                        case 'cgi':         // php-cgi < 5.3
+                        case 'cgi-fcgi':    // php-cgi >= 5.3
+                        case 'fpm-fcgi':    // php-fpm >= 5.3.3
+                        header('Status: 304 Not Modified');
+                        break;
+
+                        case 'cli':
+                        if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) {
+                            $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
+                        }
+                        break;
+
+                        default:
+                        header('HTTP/1.1 304 Not Modified');
+                        break;
+                    }
+                } else {
+                    switch (PHP_SAPI) {
+                        case 'cli':
+                        if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) {
+                            $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT';
+                        }
+                        break;
+
+                        default:
+                        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT');
+                        break;
+                    }
+                    echo $_output;
+                }
+            } else {
+                echo $_output;
+            }
+            // debug output
+            if ($this->smarty->debugging) {
+                Smarty_Internal_Debug::display_debug($this);
+            }
+            if ($merge_tpl_vars) {
+                // restore local variables
+                $_template->tpl_vars = $save_tpl_vars;
+                $_template->config_vars =  $save_config_vars;
+            }
+            return;
+        } else {
+            if ($merge_tpl_vars) {
+                // restore local variables
+                $_template->tpl_vars = $save_tpl_vars;
+                $_template->config_vars =  $save_config_vars;
+            }
+            // return fetched content
+            return $_output;
+        }
+    }
+
+    /**
+     * displays a Smarty template
+     *
+     * @param string $template   the resource handle of the template file or template object
+     * @param mixed  $cache_id   cache id to be used with this template
+     * @param mixed  $compile_id compile id to be used with this template
+     * @param object $parent     next higher level of Smarty variables
+     */
+    public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
+    {
+        // display template
+        $this->fetch($template, $cache_id, $compile_id, $parent, true);
+    }
+
+    /**
+     * test if cache is valid
+     *
+     * @param string|object $template   the resource handle of the template file or template object
+     * @param mixed         $cache_id   cache id to be used with this template
+     * @param mixed         $compile_id compile id to be used with this template
+     * @param object        $parent     next higher level of Smarty variables
+     * @return boolean cache status
+     */
+    public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
+    {
+        if ($template === null && $this instanceof $this->template_class) {
+            return $this->cached->valid;
+        }
+        if (!($template instanceof $this->template_class)) {
+            if ($parent === null) {
+                $parent = $this;
+            }
+            $template = $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
+        }
+        // return cache status of template
+        return $template->cached->valid;
+    }
+
+    /**
+     * creates a data object
+     *
+     * @param object $parent next higher level of Smarty variables
+     * @returns Smarty_Data data object
+     */
+    public function createData($parent = null)
+    {
+        return new Smarty_Data($parent, $this);
+    }
+
+    /**
+     * Registers plugin to be used in templates
+     *
+     * @param string   $type       plugin type
+     * @param string   $tag        name of template tag
+     * @param callback $callback   PHP callback to register
+     * @param boolean  $cacheable  if true (default) this fuction is cachable
+     * @param array    $cache_attr caching attributes if any
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException when the plugin tag is invalid
+     */
+    public function registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = null)
+    {
+        if (isset($this->smarty->registered_plugins[$type][$tag])) {
+            throw new SmartyException("Plugin tag \"{$tag}\" already registered");
+        } elseif (!is_callable($callback)) {
+            throw new SmartyException("Plugin \"{$tag}\" not callable");
+        } else {
+            $this->smarty->registered_plugins[$type][$tag] = array($callback, (bool) $cacheable, (array) $cache_attr);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Unregister Plugin
+     *
+     * @param string $type of plugin
+     * @param string $tag name of plugin
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unregisterPlugin($type, $tag)
+    {
+        if (isset($this->smarty->registered_plugins[$type][$tag])) {
+            unset($this->smarty->registered_plugins[$type][$tag]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type name of resource type
+     * @param Smarty_Resource|array $callback or instance of Smarty_Resource, or array of callbacks to handle resource (deprecated)
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function registerResource($type, $callback)
+    {
+        $this->smarty->registered_resources[$type] = $callback instanceof Smarty_Resource ? $callback : array($callback, false);
+        return $this;
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource type
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unregisterResource($type)
+    {
+        if (isset($this->smarty->registered_resources[$type])) {
+            unset($this->smarty->registered_resources[$type]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers a cache resource to cache a template's output
+     *
+     * @param string               $type     name of cache resource type
+     * @param Smarty_CacheResource $callback instance of Smarty_CacheResource to handle output caching
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function registerCacheResource($type, Smarty_CacheResource $callback)
+    {
+        $this->smarty->registered_cache_resources[$type] = $callback;
+        return $this;
+    }
+
+    /**
+     * Unregisters a cache resource
+     *
+     * @param string $type name of cache resource type
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unregisterCacheResource($type)
+    {
+        if (isset($this->smarty->registered_cache_resources[$type])) {
+            unset($this->smarty->registered_cache_resources[$type]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string  $object        name of template object
+     * @param object  $object_impl   the referenced PHP object to register
+     * @param array   $allowed       list of allowed methods (empty = all)
+     * @param boolean $smarty_args   smarty argument format, else traditional
+     * @param array   $block_methods list of block-methods
+     * @param array $block_functs list of methods that are block format
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException if any of the methods in $allowed or $block_methods are invalid
+     */
+    public function registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        // test if allowed methodes callable
+        if (!empty($allowed)) {
+            foreach ((array) $allowed as $method) {
+                if (!is_callable(array($object_impl, $method))) {
+                    throw new SmartyException("Undefined method '$method' in registered object");
+                }
+            }
+        }
+        // test if block methodes callable
+        if (!empty($block_methods)) {
+            foreach ((array) $block_methods as $method) {
+                if (!is_callable(array($object_impl, $method))) {
+                    throw new SmartyException("Undefined method '$method' in registered object");
+                }
+            }
+        }
+        // register the object
+        $this->smarty->registered_objects[$object_name] =
+        array($object_impl, (array) $allowed, (boolean) $smarty_args, (array) $block_methods);
+        return $this;
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name object name
+     * @return object
+     * @throws SmartyException if no such object is found
+     */
+    public function getRegisteredObject($name)
+    {
+        if (!isset($this->smarty->registered_objects[$name])) {
+            throw new SmartyException("'$name' is not a registered object");
+        }
+        if (!is_object($this->smarty->registered_objects[$name][0])) {
+            throw new SmartyException("registered '$name' is not an object");
+        }
+        return $this->smarty->registered_objects[$name][0];
+    }
+
+    /**
+     * unregister an object
+     *
+     * @param string $name object name
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unregisterObject($name)
+    {
+        if (isset($this->smarty->registered_objects[$name])) {
+            unset($this->smarty->registered_objects[$name]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers static classes to be used in templates
+     *
+     * @param string $class name of template class
+     * @param string $class_impl the referenced PHP class to register
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException if $class_impl does not refer to an existing class
+     */
+    public function registerClass($class_name, $class_impl)
+    {
+        // test if exists
+        if (!class_exists($class_impl)) {
+            throw new SmartyException("Undefined class '$class_impl' in register template class");
+        }
+        // register the class
+        $this->smarty->registered_classes[$class_name] = $class_impl;
+        return $this;
+    }
+
+    /**
+     * Registers a default plugin handler
+     *
+     * @param callable $callback class/method name
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException if $callback is not callable
+     */
+    public function registerDefaultPluginHandler($callback)
+    {
+        if (is_callable($callback)) {
+            $this->smarty->default_plugin_handler_func = $callback;
+        } else {
+            throw new SmartyException("Default plugin handler '$callback' not callable");
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers a default template handler
+     *
+     * @param callable $callback class/method name
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException if $callback is not callable
+     */
+    public function registerDefaultTemplateHandler($callback)
+    {
+        if (is_callable($callback)) {
+            $this->smarty->default_template_handler_func = $callback;
+        } else {
+            throw new SmartyException("Default template handler '$callback' not callable");
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers a default template handler
+     *
+     * @param callable $callback class/method name
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     * @throws SmartyException if $callback is not callable
+     */
+    public function registerDefaultConfigHandler($callback)
+    {
+        if (is_callable($callback)) {
+            $this->smarty->default_config_handler_func = $callback;
+        } else {
+            throw new SmartyException("Default config handler '$callback' not callable");
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Registers a filter function
+     *
+     * @param string $type filter type
+     * @param callback $callback
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function registerFilter($type, $callback)
+    {
+        $this->smarty->registered_filters[$type][$this->_get_filter_name($callback)] = $callback;
+        return $this;
+    }
+
+    /**
+     * Unregisters a filter function
+     *
+     * @param string $type filter type
+     * @param callback $callback
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unregisterFilter($type, $callback)
+    {
+        $name = $this->_get_filter_name($callback);
+        if (isset($this->smarty->registered_filters[$type][$name])) {
+            unset($this->smarty->registered_filters[$type][$name]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * Return internal filter name
+     *
+     * @param callback $function_name
+     * @return string internal filter name
+     */
+    public function _get_filter_name($function_name)
+    {
+        if (is_array($function_name)) {
+            $_class_name = (is_object($function_name[0]) ?
+            get_class($function_name[0]) : $function_name[0]);
+            return $_class_name . '_' . $function_name[1];
+        } else {
+            return $function_name;
+        }
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     * @throws SmartyException if filter could not be loaded
+     */
+    public function loadFilter($type, $name)
+    {
+        $_plugin = "smarty_{$type}filter_{$name}";
+        $_filter_name = $_plugin;
+        if ($this->smarty->loadPlugin($_plugin)) {
+            if (class_exists($_plugin, false)) {
+                $_plugin = array($_plugin, 'execute');
+            }
+            if (is_callable($_plugin)) {
+                $this->smarty->registered_filters[$type][$_filter_name] = $_plugin;
+                return true;
+            }
+        }
+        throw new SmartyException("{$type}filter \"{$name}\" not callable");
+    }
+
+    /**
+     * unload a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+     */
+    public function unloadFilter($type, $name)
+    {
+        $_filter_name = "smarty_{$type}filter_{$name}";
+        if (isset($this->smarty->registered_filters[$type][$_filter_name])) {
+            unset ($this->smarty->registered_filters[$type][$_filter_name]);
+        }
+        
+        return $this;
+    }
+
+    /**
+     * preg_replace callback to convert camelcase getter/setter to underscore property names
+     *
+     * @param string $match match string
+     * @return string replacemant
+     */
+    private function replaceCamelcase($match) {
+        return "_" . strtolower($match[1]);
+    }
+
+    /**
+     * Handle unknown class methods
+     *
+     * @param string $name unknown method-name
+     * @param array  $args argument array
+     */
+    public function __call($name, $args)
+    {
+        static $_prefixes = array('set' => true, 'get' => true);
+        static $_resolved_property_name = array();
+        static $_resolved_property_source = array();
+
+        // method of Smarty object?
+        if (method_exists($this->smarty, $name)) {
+            return call_user_func_array(array($this->smarty, $name), $args);
+        }
+        // see if this is a set/get for a property
+        $first3 = strtolower(substr($name, 0, 3));
+        if (isset($_prefixes[$first3]) && isset($name[3]) && $name[3] !== '_') {
+            if (isset($_resolved_property_name[$name])) {
+                $property_name = $_resolved_property_name[$name];
+            } else {
+                // try to keep case correct for future PHP 6.0 case-sensitive class methods
+                // lcfirst() not available < PHP 5.3.0, so improvise
+                $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4);
+                // convert camel case to underscored name
+                $property_name = preg_replace_callback('/([A-Z])/', array($this,'replaceCamelcase'), $property_name);
+                $_resolved_property_name[$name] = $property_name;
+            }
+            if (isset($_resolved_property_source[$property_name])) {
+                $_is_this = $_resolved_property_source[$property_name];
+            } else {
+                $_is_this = null;
+                if (property_exists($this, $property_name)) {
+                    $_is_this = true;
+                } else if (property_exists($this->smarty, $property_name)) {
+                    $_is_this = false;
+                }
+                $_resolved_property_source[$property_name] = $_is_this;
+            }
+            if ($_is_this) {
+                if ($first3 == 'get')
+                return $this->$property_name;
+                else
+                return $this->$property_name = $args[0];
+            } else if ($_is_this === false) {
+                if ($first3 == 'get')
+                return $this->smarty->$property_name;
+                else
+                return $this->smarty->$property_name = $args[0];
+            } else {
+                throw new SmartyException("property '$property_name' does not exist.");
+                return false;
+            }
+        }
+        if ($name == 'Smarty') {
+            throw new SmartyException("PHP5 requires you to call __construct() instead of Smarty()");
+        }
+        // must be unknown
+        throw new SmartyException("Call of unknown method '$name'.");
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatecompilerbase.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatecompilerbase.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatecompilerbase.php	(revision 345)
@@ -0,0 +1,626 @@
+<?php
+/**
+ * Smarty Internal Plugin Smarty Template Compiler Base
+ *
+ * This file contains the basic classes and methodes for compiling Smarty templates with lexer/parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Main abstract compiler class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+abstract class Smarty_Internal_TemplateCompilerBase {
+
+    /**
+     * hash for nocache sections
+     *
+     * @var mixed
+     */
+    private $nocache_hash = null;
+    /**
+     * suppress generation of nocache code
+     *
+     * @var bool
+     */
+    public $suppressNocacheProcessing = false;
+    /**
+     * suppress generation of merged template code
+     *
+     * @var bool
+     */
+    public $suppressMergedTemplates = false;
+    /**
+     * compile tag objects
+     *
+     * @var array
+     */
+    public static $_tag_objects = array();
+    /**
+     * tag stack
+     *
+     * @var array
+     */
+    public $_tag_stack = array();
+    /**
+     * current template
+     *
+     * @var Smarty_Internal_Template
+     */
+    public $template = null;
+    /**
+     * merged templates
+     *
+     * @var array
+     */
+    public $merged_templates = array();
+    /**
+     * flag when compiling {block}
+     *
+     * @var bool
+     */
+    public $inheritance = false;
+    /**
+     * plugins loaded by default plugin handler
+     *
+     * @var array
+     */
+    public $default_handler_plugins = array();
+    /**
+     * saved preprocessed modifier list
+     *
+     * @var mixed
+     */
+    public $default_modifier_list = null;
+    /**
+     * force compilation of complete template as nocache
+     * @var boolean
+     */
+    public $forceNocache = false;
+    /**
+     * suppress Smarty header code in compiled template
+     * @var bool
+     */
+    public $suppressHeader = false;
+    /**
+     * suppress template property header code in compiled template
+     * @var bool
+     */
+    public $suppressTemplatePropertyHeader = false;
+    /**
+     * flag if compiled template file shall we written
+     * @var bool
+     */
+    public $write_compiled_code = true;
+    /**
+     * flag if currently a template function is compiled
+     * @var bool
+     */
+    public $compiles_template_function = false;
+    /**
+     * called subfuntions from template function
+     * @var array
+     */
+    public $called_functions = array();
+    /**
+     * flags for used modifier plugins
+     * @var array
+     */
+    public $modifier_plugins = array();
+
+    /**
+     * Initialize compiler
+     */
+    public function __construct()
+    {
+        $this->nocache_hash = str_replace('.', '-', uniqid(rand(), true));
+    }
+
+    /**
+     * Method to compile a Smarty template
+     *
+     * @param  Smarty_Internal_Template $template template object to compile
+     * @return bool true if compiling succeeded, false if it failed
+     */
+    public function compileTemplate(Smarty_Internal_Template $template)
+    {
+        if (empty($template->properties['nocache_hash'])) {
+            $template->properties['nocache_hash'] = $this->nocache_hash;
+        } else {
+            $this->nocache_hash = $template->properties['nocache_hash'];
+        }
+        // flag for nochache sections
+        $this->nocache = false;
+        $this->tag_nocache = false;
+        // save template object in compiler class
+        $this->template = $template;
+        // reset has noche code flag
+        $this->template->has_nocache_code = false;
+        $this->smarty->_current_file = $saved_filepath = $this->template->source->filepath;
+        // template header code
+        $template_header = '';
+        if (!$this->suppressHeader) {
+            $template_header .= "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
+            $template_header .= "         compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
+        }
+
+        do {
+            // flag for aborting current and start recompile
+            $this->abort_and_recompile = false;
+            // get template source
+            $_content = $template->source->content;
+            // run prefilter if required
+            if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) {
+                $template->source->content = $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
+            }
+            // on empty template just return header
+            if ($_content == '') {
+                if ($this->suppressTemplatePropertyHeader) {
+                    $code = '';
+                } else {
+                    $code = $template_header . $template->createTemplateCodeFrame();
+                }
+                return $code;
+            }
+            // call compiler
+            $_compiled_code = $this->doCompile($_content);
+        } while ($this->abort_and_recompile);
+        $this->template->source->filepath = $saved_filepath;
+        // free memory
+        unset($this->parser->root_buffer, $this->parser->current_buffer, $this->parser, $this->lex, $this->template);
+        self::$_tag_objects = array();
+        // return compiled code to template object
+        $merged_code = '';
+        if (!$this->suppressMergedTemplates) {
+            foreach ($this->merged_templates as $code) {
+                $merged_code .= $code;
+            }
+        }
+        if ($this->suppressTemplatePropertyHeader) {
+            $code = $_compiled_code . $merged_code;
+        } else {
+            $code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
+        }
+        // run postfilter if required
+        if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
+            $code = Smarty_Internal_Filter_Handler::runFilter('post', $code, $template);
+        }
+        return $code;
+    }
+
+    /**
+     * Compile Tag
+     *
+     * This is a call back from the lexer/parser
+     * It executes the required compile plugin for the Smarty tag
+     *
+     * @param string $tag       tag name
+     * @param array  $args      array with tag attributes
+     * @param array  $parameter array with compilation parameter
+     * @return string compiled code
+     */
+    public function compileTag($tag, $args, $parameter = array())
+    {
+        // $args contains the attributes parsed and compiled by the lexer/parser
+        // assume that tag does compile into code, but creates no HTML output
+        $this->has_code = true;
+        $this->has_output = false;
+        // log tag/attributes
+        if (isset($this->smarty->get_used_tags) && $this->smarty->get_used_tags) {
+            $this->template->used_tags[] = array($tag, $args);
+        }
+        // check nocache option flag
+        if (in_array("'nocache'",$args) || in_array(array('nocache'=>'true'),$args)
+        || in_array(array('nocache'=>'"true"'),$args) || in_array(array('nocache'=>"'true'"),$args)) {
+            $this->tag_nocache = true;
+        }
+        // compile the smarty tag (required compile classes to compile the tag are autoloaded)
+        if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
+            if (isset($this->smarty->template_functions[$tag])) {
+                // template defined by {template} tag
+                $args['_attr']['name'] = "'" . $tag . "'";
+                $_output = $this->callTagCompiler('call', $args, $parameter);
+            }
+        }
+        if ($_output !== false) {
+            if ($_output !== true) {
+                // did we get compiled code
+                if ($this->has_code) {
+                    // Does it create output?
+                    if ($this->has_output) {
+                        $_output .= "\n";
+                    }
+                    // return compiled code
+                    return $_output;
+                }
+            }
+            // tag did not produce compiled code
+            return '';
+        } else {
+            // map_named attributes
+            if (isset($args['_attr'])) {
+                foreach ($args['_attr'] as $key => $attribute) {
+                    if (is_array($attribute)) {
+                        $args = array_merge($args, $attribute);
+                    }
+                }
+            }
+            // not an internal compiler tag
+            if (strlen($tag) < 6 || substr($tag, -5) != 'close') {
+                // check if tag is a registered object
+                if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
+                    $methode = $parameter['object_methode'];
+                    if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
+                    (empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) {
+                        return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
+                    } elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
+                        return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
+                    } else {
+                        return $this->trigger_template_error ('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno);
+                    }
+                }
+                // check if tag is registered
+                foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK) as $plugin_type) {
+                    if (isset($this->smarty->registered_plugins[$plugin_type][$tag])) {
+                        // if compiler function plugin call it now
+                        if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+                            $new_args = array();
+                            foreach ($args as $key => $mixed) {
+                            	if (is_array($mixed)) {
+                                	$new_args = array_merge($new_args, $mixed);
+                                } else {
+                                	$new_args[$key] = $mixed;
+                                }
+                            }
+                            if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
+                                $this->tag_nocache = true;
+                            }
+                            $function = $this->smarty->registered_plugins[$plugin_type][$tag][0];
+                            if (!is_array($function)) {
+                                return $function($new_args, $this);
+                            } else if (is_object($function[0])) {
+                                return $this->smarty->registered_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+                            } else {
+                                return call_user_func_array($function, array($new_args, $this));
+                            }
+                        }
+                        // compile registered function or block function
+                        if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) {
+                            return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+                        }
+
+                    }
+                }
+                // check plugins from plugins folder
+                foreach ($this->smarty->plugin_search_order as $plugin_type) {
+                    if ($plugin_type == Smarty::PLUGIN_BLOCK && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))) {
+                        $plugin = 'smarty_compiler_' . $tag;
+                        if (is_callable($plugin)) {
+                            // convert arguments format for old compiler plugins
+                            $new_args = array();
+                            foreach ($args as $key => $mixed) {
+                            	if (is_array($mixed)) {
+                                	$new_args = array_merge($new_args, $mixed);
+                                } else {
+                                	$new_args[$key] = $mixed;
+                                }
+                            }
+                            return $plugin($new_args, $this->smarty);
+                        }
+                        if (class_exists($plugin, false)) {
+                            $plugin_object = new $plugin;
+                            if (method_exists($plugin_object, 'compile')) {
+                                return $plugin_object->compile($args, $this);
+                            }
+                        }
+                        throw new SmartyException("Plugin \"{$tag}\" not callable");
+                    } else {
+                        if ($function = $this->getPlugin($tag, $plugin_type)) {
+                            if(!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+                                return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function);
+                            }
+                        }
+                    }
+                }
+                if (is_callable($this->smarty->default_plugin_handler_func)) {
+                    $found = false;
+                    // look for already resolved tags
+                    foreach ($this->smarty->plugin_search_order as $plugin_type) {
+                        if (isset($this->default_handler_plugins[$plugin_type][$tag])) {
+                            $found = true;
+                            break;
+                        }
+                    }
+                    if (!$found) {
+                        // call default handler
+                        foreach ($this->smarty->plugin_search_order as $plugin_type) {
+                            if ($this->getPluginFromDefaultHandler($tag, $plugin_type)) {
+                                $found = true;
+                                break;
+                            }
+                        }
+                    }
+                    if ($found) {
+                        // if compiler function plugin call it now
+                        if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+                            $new_args = array();
+                            foreach ($args as $mixed) {
+                                $new_args = array_merge($new_args, $mixed);
+                            }
+                            $function = $this->default_handler_plugins[$plugin_type][$tag][0];
+                            if (!is_array($function)) {
+                                return $function($new_args, $this);
+                            } else if (is_object($function[0])) {
+                                return $this->default_handler_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+                            } else {
+                                return call_user_func_array($function, array($new_args, $this));
+                            }
+                        } else {
+                            return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+                        }
+                    }
+                }
+            } else {
+                // compile closing tag of block function
+                $base_tag = substr($tag, 0, -5);
+                // check if closing tag is a registered object
+                if (isset($this->smarty->registered_objects[$base_tag]) && isset($parameter['object_methode'])) {
+                    $methode = $parameter['object_methode'];
+                    if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) {
+                        return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
+                    } else {
+                        return $this->trigger_template_error ('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno);
+                    }
+                }
+                // registered block tag ?
+                if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag]) || isset($this->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+                    return $this->callTagCompiler('private_registered_block', $args, $parameter, $tag);
+                }
+                // block plugin?
+                if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
+                    return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
+                }
+                if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
+                    $plugin = 'smarty_compiler_' . $tag;
+                    if (is_callable($plugin)) {
+                        return $plugin($args, $this->smarty);
+                    }
+                    if (class_exists($plugin, false)) {
+                        $plugin_object = new $plugin;
+                        if (method_exists($plugin_object, 'compile')) {
+                            return $plugin_object->compile($args, $this);
+                        }
+                    }
+                    throw new SmartyException("Plugin \"{$tag}\" not callable");
+                }
+            }
+            $this->trigger_template_error ("unknown tag \"" . $tag . "\"", $this->lex->taglineno);
+        }
+    }
+
+    /**
+     * lazy loads internal compile plugin for tag and calls the compile methode
+     *
+     * compile objects cached for reuse.
+     * class name format:  Smarty_Internal_Compile_TagName
+     * plugin filename format: Smarty_Internal_Tagname.php
+     *
+     * @param string $tag   tag name
+     * @param array $args   list of tag attributes
+     * @param mixed $param1 optional parameter
+     * @param mixed $param2 optional parameter
+     * @param mixed $param3 optional parameter
+     * @return string compiled code
+     */
+    public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null)
+    {
+        // re-use object if already exists
+        if (isset(self::$_tag_objects[$tag])) {
+            // compile this tag
+            return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
+        }
+        // lazy load internal compiler plugin
+        $class_name = 'Smarty_Internal_Compile_' . $tag;
+        if ($this->smarty->loadPlugin($class_name)) {
+            // check if tag allowed by security
+            if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+            // use plugin if found
+            self::$_tag_objects[$tag] = new $class_name;
+            // compile this tag
+            return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
+            }
+        }
+        // no internal compile plugin for this tag
+        return false;
+    }
+
+    /**
+     * Check for plugins and return function name
+     *
+     * @param string $pugin_name  name of plugin or function
+     * @param string $plugin_type type of plugin
+     * @return string call name of function
+     */
+    public function getPlugin($plugin_name, $plugin_type)
+    {
+        $function = null;
+        if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+            if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+                $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+            } else if (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+                $this->template->required_plugins['nocache'][$plugin_name][$plugin_type] = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type];
+                $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+            }
+        } else {
+            if (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+                $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+            } else if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+                $this->template->required_plugins['compiled'][$plugin_name][$plugin_type] = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type];
+                $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+            }
+        }
+        if (isset($function)) {
+            if ($plugin_type == 'modifier') {
+                $this->modifier_plugins[$plugin_name] = true;
+            }
+            return $function;
+        }
+        // loop through plugin dirs and find the plugin
+        $function = 'smarty_' . $plugin_type . '_' . $plugin_name;
+        $file = $this->smarty->loadPlugin($function, false);
+
+        if (is_string($file)) {
+            if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+                $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['file'] = $file;
+                $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'] = $function;
+            } else {
+                $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['file'] = $file;
+                $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'] = $function;
+            }
+            if ($plugin_type == 'modifier') {
+                $this->modifier_plugins[$plugin_name] = true;
+            }
+            return $function;
+        }
+        if (is_callable($function)) {
+            // plugin function is defined in the script
+            return $function;
+        }
+        return false;
+    }
+
+    /**
+     * Check for plugins by default plugin handler
+     *
+     * @param string $tag         name of tag
+     * @param string $plugin_type type of plugin
+     * @return boolean true if found
+     */
+    public function getPluginFromDefaultHandler($tag, $plugin_type)
+    {
+        $callback = null;
+        $script = null;
+        $result = call_user_func_array(
+            $this->smarty->default_plugin_handler_func,
+            array($tag, $plugin_type, $this->template, &$callback, &$script)
+        );
+        if ($result) {
+            if ($script !== null) {
+                if (is_file($script)) {
+                    if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+                        $this->template->required_plugins['nocache'][$tag][$plugin_type]['file'] = $script;
+                        $this->template->required_plugins['nocache'][$tag][$plugin_type]['function'] = $callback;
+                    } else {
+                        $this->template->required_plugins['compiled'][$tag][$plugin_type]['file'] = $script;
+                        $this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback;
+                    }
+                    include_once $script;
+                }  else {
+                    $this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
+                }
+            }
+            if (!is_string($callback) && !(is_array($callback) && is_string($callback[0]) && is_string($callback[1]))) {
+                $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" must be a static function name or array of class and function name");
+            }
+            if (is_callable($callback)) {
+                $this->default_handler_plugins[$plugin_type][$tag] = array($callback, true, array());
+                return true;
+            } else {
+                $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" not callable");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Inject inline code for nocache template sections
+     *
+     * This method gets the content of each template element from the parser.
+     * If the content is compiled code and it should be not cached the code is injected
+     * into the rendered output.
+     *
+     * @param string  $content content of template element
+     * @param boolean $is_code true if content is compiled code
+     * @return string content
+     */
+    public function processNocacheCode($content, $is_code)
+    {
+        // If the template is not evaluated and we have a nocache section and or a nocache tag
+        if ($is_code && !empty($content)) {
+            // generate replacement code
+            if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
+            ($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
+                $this->template->has_nocache_code = true;
+                $_output = str_replace("'", "\'", $content);
+                $_output = str_replace('\\\\', '\\\\\\\\', $_output);
+                $_output = str_replace("^#^", "'", $_output);
+                $_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
+                // make sure we include modifer plugins for nocache code
+                foreach ($this->modifier_plugins as $plugin_name => $dummy) {
+                    if (isset($this->template->required_plugins['compiled'][$plugin_name]['modifier'])) {
+                        $this->template->required_plugins['nocache'][$plugin_name]['modifier'] = $this->template->required_plugins['compiled'][$plugin_name]['modifier'];
+                    }
+                }
+            } else {
+                $_output = $content;
+            }
+        } else {
+            $_output = $content;
+        }
+        $this->modifier_plugins = array();
+        $this->suppressNocacheProcessing = false;
+        $this->tag_nocache = false;
+        return $_output;
+    }
+
+    /**
+     * display compiler error messages without dying
+     *
+     * If parameter $args is empty it is a parser detected syntax error.
+     * In this case the parser is called to obtain information about expected tokens.
+     *
+     * If parameter $args contains a string this is used as error message
+     *
+     * @param string $args individual error message or null
+     * @param string $line line-number
+     * @throws SmartyCompilerException when an unexpected token is found
+     */
+    public function trigger_template_error($args = null, $line = null)
+    {
+        // get template source line which has error
+        if (!isset($line)) {
+            $line = $this->lex->line;
+        }
+        $match = preg_split("/\n/", $this->lex->data);
+        $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '"  on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!',' ',$match[$line-1]))) . '" ';
+        if (isset($args)) {
+            // individual error message
+            $error_text .= $args;
+        } else {
+            // expected token from parser
+            $error_text .= ' - Unexpected "' . $this->lex->value.'"';
+            if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4 ) {
+                foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
+                    $exp_token = $this->parser->yyTokenName[$token];
+                    if (isset($this->lex->smarty_token_names[$exp_token])) {
+                        // token type from lexer
+                        $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
+                    } else {
+                        // otherwise internal token name
+                        $expect[] = $this->parser->yyTokenName[$token];
+                    }
+                }
+                $error_text .= ', expected one of: ' . implode(' , ', $expect);
+            }
+        }
+        throw new SmartyCompilerException($error_text);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatelexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatelexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatelexer.php	(revision 345)
@@ -0,0 +1,1161 @@
+<?php
+/**
+* Smarty Internal Plugin Templatelexer
+*
+* This is the lexer to break the template source into tokens
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+/**
+* Smarty Internal Plugin Templatelexer
+*/
+class Smarty_Internal_Templatelexer
+{
+    public $data;
+    public $counter;
+    public $token;
+    public $value;
+    public $node;
+    public $line;
+    public $taglineno;
+    public $state = 1;
+    private $heredoc_id_stack = Array();
+    public $smarty_token_names = array (		// Text for parser error messages
+    				'IDENTITY'	=> '===',
+    				'NONEIDENTITY'	=> '!==',
+    				'EQUALS'	=> '==',
+    				'NOTEQUALS'	=> '!=',
+    				'GREATEREQUAL' => '(>=,ge)',
+    				'LESSEQUAL' => '(<=,le)',
+    				'GREATERTHAN' => '(>,gt)',
+    				'LESSTHAN' => '(<,lt)',
+    				'MOD' => '(%,mod)',
+    				'NOT'			=> '(!,not)',
+    				'LAND'		=> '(&&,and)',
+    				'LOR'			=> '(||,or)',
+    				'LXOR'			=> 'xor',
+    				'OPENP'		=> '(',
+    				'CLOSEP'	=> ')',
+    				'OPENB'		=> '[',
+    				'CLOSEB'	=> ']',
+    				'PTR'			=> '->',
+    				'APTR'		=> '=>',
+    				'EQUAL'		=> '=',
+    				'NUMBER'	=> 'number',
+    				'UNIMATH'	=> '+" , "-',
+    				'MATH'		=> '*" , "/" , "%',
+    				'INCDEC'	=> '++" , "--',
+    				'SPACE'		=> ' ',
+    				'DOLLAR'	=> '$',
+    				'SEMICOLON' => ';',
+    				'COLON'		=> ':',
+    				'DOUBLECOLON'		=> '::',
+    				'AT'		=> '@',
+    				'HATCH'		=> '#',
+    				'QUOTE'		=> '"',
+    				'BACKTICK'		=> '`',
+    				'VERT'		=> '|',
+    				'DOT'			=> '.',
+    				'COMMA'		=> '","',
+    				'ANDSYM'		=> '"&"',
+    				'QMARK'		=> '"?"',
+    				'ID'			=> 'identifier',
+    				'TEXT'		=> 'text',
+     				'FAKEPHPSTARTTAG'	=> 'Fake PHP start tag',
+     				'PHPSTARTTAG'	=> 'PHP start tag',
+     				'PHPENDTAG'	=> 'PHP end tag',
+ 						'LITERALSTART'  => 'Literal start',
+ 						'LITERALEND'    => 'Literal end',
+    				'LDELSLASH' => 'closing tag',
+    				'COMMENT' => 'comment',
+    				'AS' => 'as',
+    				'TO' => 'to',
+    				);
+
+
+    function __construct($data,$compiler)
+    {
+//        $this->data = preg_replace("/(\r\n|\r|\n)/", "\n", $data);
+        $this->data = $data;
+        $this->counter = 0;
+        $this->line = 1;
+        $this->smarty = $compiler->smarty;
+        $this->compiler = $compiler;
+        $this->ldel = preg_quote($this->smarty->left_delimiter,'/');
+        $this->ldel_length = strlen($this->smarty->left_delimiter);
+        $this->rdel = preg_quote($this->smarty->right_delimiter,'/');
+        $this->smarty_token_names['LDEL'] =	$this->smarty->left_delimiter;
+        $this->smarty_token_names['RDEL'] =	$this->smarty->right_delimiter;
+        $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
+     }
+
+
+    private $_yy_state = 1;
+    private $_yy_stack = array();
+
+    function yylex()
+    {
+        return $this->{'yylex' . $this->_yy_state}();
+    }
+
+    function yypushstate($state)
+    {
+        array_push($this->_yy_stack, $this->_yy_state);
+        $this->_yy_state = $state;
+    }
+
+    function yypopstate()
+    {
+        $this->_yy_state = array_pop($this->_yy_stack);
+    }
+
+    function yybegin($state)
+    {
+        $this->_yy_state = $state;
+    }
+
+
+
+    function yylex1()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 1,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+              8 => 0,
+              9 => 0,
+              10 => 0,
+              11 => 1,
+              13 => 0,
+              14 => 0,
+              15 => 0,
+              16 => 0,
+              17 => 0,
+              18 => 0,
+              19 => 0,
+              20 => 0,
+              21 => 0,
+              22 => 0,
+              23 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(".$this->ldel."[$]smarty\\.block\\.child".$this->rdel.")|\G(\\{\\})|\G(".$this->ldel."\\*([\S\s]*?)\\*".$this->rdel.")|\G(".$this->ldel."strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s*setfilter\\s+)|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state TEXT');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r1_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const TEXT = 1;
+    function yy_r1_1($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILD;
+    }
+    function yy_r1_2($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+    function yy_r1_3($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_COMMENT;
+    }
+    function yy_r1_5($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+    }
+    function yy_r1_6($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+    $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+    $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+  }
+    }
+    function yy_r1_7($yy_subpatterns)
+    {
+
+    $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+    }
+    function yy_r1_8($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+    $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+  }
+    }
+    function yy_r1_9($yy_subpatterns)
+    {
+
+   $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
+   $this->yypushstate(self::LITERAL);
+    }
+    function yy_r1_10($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_11($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_13($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_14($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_15($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_16($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r1_17($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r1_18($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r1_19($yy_subpatterns)
+    {
+
+  if (in_array($this->value, Array('<?', '<?=', '<?php'))) {
+    $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
+  } elseif ($this->value == '<?xml') {
+      $this->token = Smarty_Internal_Templateparser::TP_XMLTAG;
+  } else {
+    $this->token = Smarty_Internal_Templateparser::TP_FAKEPHPSTARTTAG;
+    $this->value = substr($this->value, 0, 2);
+  }
+     }
+    function yy_r1_20($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_PHPENDTAG;
+    }
+    function yy_r1_21($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
+    }
+    function yy_r1_22($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
+    }
+    function yy_r1_23($yy_subpatterns)
+    {
+
+  $to = strlen($this->data);
+  preg_match("/{$this->ldel}|<\?|\?>|<%|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+  if (isset($match[0][1])) {
+    $to = $match[0][1];
+  }
+  $this->value = substr($this->data,$this->counter,$to-$this->counter);
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+
+
+    function yylex2()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 1,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+              8 => 0,
+              9 => 0,
+              10 => 0,
+              11 => 0,
+              12 => 0,
+              13 => 0,
+              14 => 0,
+              15 => 0,
+              16 => 0,
+              17 => 0,
+              18 => 0,
+              19 => 0,
+              20 => 1,
+              22 => 1,
+              24 => 1,
+              26 => 0,
+              27 => 0,
+              28 => 0,
+              29 => 0,
+              30 => 0,
+              31 => 0,
+              32 => 0,
+              33 => 0,
+              34 => 0,
+              35 => 0,
+              36 => 0,
+              37 => 0,
+              38 => 0,
+              39 => 0,
+              40 => 0,
+              41 => 0,
+              42 => 0,
+              43 => 3,
+              47 => 0,
+              48 => 0,
+              49 => 0,
+              50 => 0,
+              51 => 0,
+              52 => 0,
+              53 => 0,
+              54 => 0,
+              55 => 1,
+              57 => 1,
+              59 => 0,
+              60 => 0,
+              61 => 0,
+              62 => 0,
+              63 => 0,
+              64 => 0,
+              65 => 0,
+              66 => 0,
+              67 => 0,
+              68 => 0,
+              69 => 0,
+              70 => 0,
+              71 => 0,
+              72 => 0,
+              73 => 0,
+              74 => 0,
+              75 => 0,
+              76 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state SMARTY');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r2_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const SMARTY = 2;
+    function yy_r2_1($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
+    }
+    function yy_r2_2($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r2_3($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r2_5($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r2_6($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r2_7($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r2_8($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_RDEL;
+  $this->yypopstate();
+    }
+    function yy_r2_9($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r2_10($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r2_11($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_RDEL;
+     $this->yypopstate();
+    }
+    function yy_r2_12($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISIN;
+    }
+    function yy_r2_13($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_AS;
+    }
+    function yy_r2_14($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TO;
+    }
+    function yy_r2_15($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_STEP;
+    }
+    function yy_r2_16($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
+    }
+    function yy_r2_17($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_IDENTITY;
+    }
+    function yy_r2_18($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_NONEIDENTITY;
+    }
+    function yy_r2_19($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_EQUALS;
+    }
+    function yy_r2_20($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_NOTEQUALS;
+    }
+    function yy_r2_22($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_GREATEREQUAL;
+    }
+    function yy_r2_24($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LESSEQUAL;
+    }
+    function yy_r2_26($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_GREATERTHAN;
+    }
+    function yy_r2_27($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LESSTHAN;
+    }
+    function yy_r2_28($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_MOD;
+    }
+    function yy_r2_29($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_NOT;
+    }
+    function yy_r2_30($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LAND;
+    }
+    function yy_r2_31($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LOR;
+    }
+    function yy_r2_32($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LXOR;
+    }
+    function yy_r2_33($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISODDBY;
+    }
+    function yy_r2_34($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISNOTODDBY;
+    }
+    function yy_r2_35($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISODD;
+    }
+    function yy_r2_36($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISNOTODD;
+    }
+    function yy_r2_37($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISEVENBY;
+    }
+    function yy_r2_38($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVENBY;
+    }
+    function yy_r2_39($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISEVEN;
+    }
+    function yy_r2_40($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVEN;
+    }
+    function yy_r2_41($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISDIVBY;
+    }
+    function yy_r2_42($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ISNOTDIVBY;
+    }
+    function yy_r2_43($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
+    }
+    function yy_r2_47($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_OPENP;
+    }
+    function yy_r2_48($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
+    }
+    function yy_r2_49($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_OPENB;
+    }
+    function yy_r2_50($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
+    }
+    function yy_r2_51($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_PTR;
+    }
+    function yy_r2_52($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_APTR;
+    }
+    function yy_r2_53($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_EQUAL;
+    }
+    function yy_r2_54($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_INCDEC;
+    }
+    function yy_r2_55($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
+    }
+    function yy_r2_57($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_MATH;
+    }
+    function yy_r2_59($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
+    }
+    function yy_r2_60($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
+    }
+    function yy_r2_61($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
+    }
+    function yy_r2_62($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_COLON;
+    }
+    function yy_r2_63($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_AT;
+    }
+    function yy_r2_64($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_HATCH;
+    }
+    function yy_r2_65($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+  $this->yypushstate(self::DOUBLEQUOTEDSTRING);
+    }
+    function yy_r2_66($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+  $this->yypopstate();
+    }
+    function yy_r2_67($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_VERT;
+    }
+    function yy_r2_68($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_DOT;
+    }
+    function yy_r2_69($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_COMMA;
+    }
+    function yy_r2_70($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ANDSYM;
+    }
+    function yy_r2_71($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_QMARK;
+    }
+    function yy_r2_72($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_HEX;
+    }
+    function yy_r2_73($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ID;
+    }
+    function yy_r2_74($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
+    }
+    function yy_r2_75($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+    }
+    function yy_r2_76($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+
+
+
+    function yylex3()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 0,
+              3 => 0,
+              4 => 0,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s*\/literal\\s*".$this->rdel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state LITERAL');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r3_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const LITERAL = 3;
+    function yy_r3_1($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
+  $this->yypushstate(self::LITERAL);
+    }
+    function yy_r3_2($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
+  $this->yypopstate();
+    }
+    function yy_r3_3($yy_subpatterns)
+    {
+
+  if (in_array($this->value, Array('<?', '<?=', '<?php'))) {
+    $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
+   } else {
+    $this->token = Smarty_Internal_Templateparser::TP_FAKEPHPSTARTTAG;
+    $this->value = substr($this->value, 0, 2);
+   }
+    }
+    function yy_r3_4($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_PHPENDTAG;
+    }
+    function yy_r3_5($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
+    }
+    function yy_r3_6($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
+    }
+    function yy_r3_7($yy_subpatterns)
+    {
+
+  $to = strlen($this->data);
+  preg_match("/{$this->ldel}\/?literal{$this->rdel}|<\?|<%|\?>|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+  if (isset($match[0][1])) {
+    $to = $match[0][1];
+  } else {
+    $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+  }
+
+  $this->value = substr($this->data,$this->counter,$to-$this->counter);
+  $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+    }
+
+
+    function yylex4()
+    {
+        $tokenMap = array (
+              1 => 0,
+              2 => 1,
+              4 => 0,
+              5 => 0,
+              6 => 0,
+              7 => 0,
+              8 => 0,
+              9 => 0,
+              10 => 0,
+              11 => 0,
+              12 => 0,
+              13 => 3,
+              17 => 0,
+            );
+        if ($this->counter >= strlen($this->data)) {
+            return false; // end of input
+        }
+        $yy_global_pattern = "/\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(\")|\G(`\\$)|\G(\\$[0-9]*[a-zA-Z_]\\w*)|\G(\\$)|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=(".$this->ldel."|\\$|`\\$|\")))|\G([\S\s])/iS";
+
+        do {
+            if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
+                $yysubmatches = $yymatches;
+                $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+                if (!count($yymatches)) {
+                    throw new Exception('Error: lexing failed because a rule matched' .
+                        ' an empty string.  Input "' . substr($this->data,
+                        $this->counter, 5) . '... state DOUBLEQUOTEDSTRING');
+                }
+                next($yymatches); // skip global match
+                $this->token = key($yymatches); // token number
+                if ($tokenMap[$this->token]) {
+                    // extract sub-patterns for passing to lex function
+                    $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+                        $tokenMap[$this->token]);
+                } else {
+                    $yysubmatches = array();
+                }
+                $this->value = current($yymatches); // token value
+                $r = $this->{'yy_r4_' . $this->token}($yysubmatches);
+                if ($r === null) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    // accept this token
+                    return true;
+                } elseif ($r === true) {
+                    // we have changed state
+                    // process this token in the new state
+                    return $this->yylex();
+                } elseif ($r === false) {
+                    $this->counter += strlen($this->value);
+                    $this->line += substr_count($this->value, "\n");
+                    if ($this->counter >= strlen($this->data)) {
+                        return false; // end of input
+                    }
+                    // skip this token
+                    continue;
+                }            } else {
+                throw new Exception('Unexpected input at line' . $this->line .
+                    ': ' . $this->data[$this->counter]);
+            }
+            break;
+        } while (true);
+
+    } // end function
+
+
+    const DOUBLEQUOTEDSTRING = 4;
+    function yy_r4_1($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r4_2($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r4_4($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r4_5($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r4_6($yy_subpatterns)
+    {
+
+  if ($this->smarty->auto_literal) {
+     $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+  } else {
+     $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+  }
+    }
+    function yy_r4_7($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r4_8($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+     $this->yypushstate(self::SMARTY);
+     $this->taglineno = $this->line;
+    }
+    function yy_r4_9($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+  $this->yypopstate();
+    }
+    function yy_r4_10($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+  $this->value = substr($this->value,0,-1);
+  $this->yypushstate(self::SMARTY);
+  $this->taglineno = $this->line;
+    }
+    function yy_r4_11($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+    }
+    function yy_r4_12($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+    function yy_r4_13($yy_subpatterns)
+    {
+
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+    function yy_r4_17($yy_subpatterns)
+    {
+
+  $to = strlen($this->data);
+  $this->value = substr($this->data,$this->counter,$to-$this->counter);
+  $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+    }
+
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templateparser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templateparser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templateparser.php	(revision 345)
@@ -0,0 +1,3265 @@
+<?php
+/**
+* Smarty Internal Plugin Templateparser
+*
+* This is the template parser.
+* It is generated from the internal.templateparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+
+class TP_yyToken implements ArrayAccess
+{
+    public $string = '';
+    public $metadata = array();
+
+    function __construct($s, $m = array())
+    {
+        if ($s instanceof TP_yyToken) {
+            $this->string = $s->string;
+            $this->metadata = $s->metadata;
+        } else {
+            $this->string = (string) $s;
+            if ($m instanceof TP_yyToken) {
+                $this->metadata = $m->metadata;
+            } elseif (is_array($m)) {
+                $this->metadata = $m;
+            }
+        }
+    }
+
+    function __toString()
+    {
+        return $this->_string;
+    }
+
+    function offsetExists($offset)
+    {
+        return isset($this->metadata[$offset]);
+    }
+
+    function offsetGet($offset)
+    {
+        return $this->metadata[$offset];
+    }
+
+    function offsetSet($offset, $value)
+    {
+        if ($offset === null) {
+            if (isset($value[0])) {
+                $x = ($value instanceof TP_yyToken) ?
+                    $value->metadata : $value;
+                $this->metadata = array_merge($this->metadata, $x);
+                return;
+            }
+            $offset = count($this->metadata);
+        }
+        if ($value === null) {
+            return;
+        }
+        if ($value instanceof TP_yyToken) {
+            if ($value->metadata) {
+                $this->metadata[$offset] = $value->metadata;
+            }
+        } elseif ($value) {
+            $this->metadata[$offset] = $value;
+        }
+    }
+
+    function offsetUnset($offset)
+    {
+        unset($this->metadata[$offset]);
+    }
+}
+
+class TP_yyStackEntry
+{
+    public $stateno;       /* The state-number */
+    public $major;         /* The major token value.  This is the code
+                     ** number for the token at this stack level */
+    public $minor; /* The user-supplied minor token value.  This
+                     ** is the value of the token  */
+};
+
+
+#line 12 "smarty_internal_templateparser.y"
+class Smarty_Internal_Templateparser#line 79 "smarty_internal_templateparser.php"
+{
+#line 14 "smarty_internal_templateparser.y"
+
+    const Err1 = "Security error: Call to private object member not allowed";
+    const Err2 = "Security error: Call to dynamic object member not allowed";
+    const Err3 = "PHP in template not allowed. Use SmartyBC to enable it";
+    // states whether the parse was successful or not
+    public $successful = true;
+    public $retvalue = 0;
+    private $lex;
+    private $internalError = false;
+    private $strip = false;
+
+    function __construct($lex, $compiler) {
+        $this->lex = $lex;
+        $this->compiler = $compiler;
+        $this->smarty = $this->compiler->smarty;
+        $this->template = $this->compiler->template;
+        $this->compiler->has_variable_string = false;
+        $this->compiler->prefix_code = array();
+        $this->prefix_number = 0;
+        $this->block_nesting_level = 0;
+        if ($this->security = isset($this->smarty->security_policy)) {
+            $this->php_handling = $this->smarty->security_policy->php_handling;
+        } else {
+            $this->php_handling = $this->smarty->php_handling;
+        }
+        $this->is_xml = false;
+        $this->asp_tags = (ini_get('asp_tags') != '0');
+        $this->current_buffer = $this->root_buffer = new _smarty_template_buffer($this);
+    }
+
+    public static function escape_start_tag($tag_text) {
+        $tag = preg_replace('/\A<\?(.*)\z/', '<<?php ?>?\1', $tag_text, -1 , $count); //Escape tag
+        return $tag;
+    }
+
+    public static function escape_end_tag($tag_text) {
+        return '?<?php ?>>';
+    }
+
+    public function compileVariable($variable) {
+        if (strpos($variable,'(') == 0) {
+            // not a variable variable
+            $var = trim($variable,'\'');
+            $this->compiler->tag_nocache=$this->compiler->tag_nocache|$this->template->getVariable($var, null, true, false)->nocache;
+            $this->template->properties['variables'][$var] = $this->compiler->tag_nocache|$this->compiler->nocache;
+        }
+//       return '(isset($_smarty_tpl->tpl_vars['. $variable .'])?$_smarty_tpl->tpl_vars['. $variable .']->value:$_smarty_tpl->getVariable('. $variable .')->value)';
+        return '$_smarty_tpl->tpl_vars['. $variable .']->value';
+    }
+#line 132 "smarty_internal_templateparser.php"
+
+    const TP_VERT                           =  1;
+    const TP_COLON                          =  2;
+    const TP_COMMENT                        =  3;
+    const TP_PHPSTARTTAG                    =  4;
+    const TP_PHPENDTAG                      =  5;
+    const TP_ASPSTARTTAG                    =  6;
+    const TP_ASPENDTAG                      =  7;
+    const TP_FAKEPHPSTARTTAG                =  8;
+    const TP_XMLTAG                         =  9;
+    const TP_TEXT                           = 10;
+    const TP_STRIPON                        = 11;
+    const TP_STRIPOFF                       = 12;
+    const TP_LITERALSTART                   = 13;
+    const TP_LITERALEND                     = 14;
+    const TP_LITERAL                        = 15;
+    const TP_LDEL                           = 16;
+    const TP_RDEL                           = 17;
+    const TP_DOLLAR                         = 18;
+    const TP_ID                             = 19;
+    const TP_EQUAL                          = 20;
+    const TP_PTR                            = 21;
+    const TP_LDELIF                         = 22;
+    const TP_LDELFOR                        = 23;
+    const TP_SEMICOLON                      = 24;
+    const TP_INCDEC                         = 25;
+    const TP_TO                             = 26;
+    const TP_STEP                           = 27;
+    const TP_LDELFOREACH                    = 28;
+    const TP_SPACE                          = 29;
+    const TP_AS                             = 30;
+    const TP_APTR                           = 31;
+    const TP_LDELSETFILTER                  = 32;
+    const TP_SMARTYBLOCKCHILD               = 33;
+    const TP_LDELSLASH                      = 34;
+    const TP_INTEGER                        = 35;
+    const TP_COMMA                          = 36;
+    const TP_OPENP                          = 37;
+    const TP_CLOSEP                         = 38;
+    const TP_MATH                           = 39;
+    const TP_UNIMATH                        = 40;
+    const TP_ANDSYM                         = 41;
+    const TP_ISIN                           = 42;
+    const TP_ISDIVBY                        = 43;
+    const TP_ISNOTDIVBY                     = 44;
+    const TP_ISEVEN                         = 45;
+    const TP_ISNOTEVEN                      = 46;
+    const TP_ISEVENBY                       = 47;
+    const TP_ISNOTEVENBY                    = 48;
+    const TP_ISODD                          = 49;
+    const TP_ISNOTODD                       = 50;
+    const TP_ISODDBY                        = 51;
+    const TP_ISNOTODDBY                     = 52;
+    const TP_INSTANCEOF                     = 53;
+    const TP_QMARK                          = 54;
+    const TP_NOT                            = 55;
+    const TP_TYPECAST                       = 56;
+    const TP_HEX                            = 57;
+    const TP_DOT                            = 58;
+    const TP_SINGLEQUOTESTRING              = 59;
+    const TP_DOUBLECOLON                    = 60;
+    const TP_AT                             = 61;
+    const TP_HATCH                          = 62;
+    const TP_OPENB                          = 63;
+    const TP_CLOSEB                         = 64;
+    const TP_EQUALS                         = 65;
+    const TP_NOTEQUALS                      = 66;
+    const TP_GREATERTHAN                    = 67;
+    const TP_LESSTHAN                       = 68;
+    const TP_GREATEREQUAL                   = 69;
+    const TP_LESSEQUAL                      = 70;
+    const TP_IDENTITY                       = 71;
+    const TP_NONEIDENTITY                   = 72;
+    const TP_MOD                            = 73;
+    const TP_LAND                           = 74;
+    const TP_LOR                            = 75;
+    const TP_LXOR                           = 76;
+    const TP_QUOTE                          = 77;
+    const TP_BACKTICK                       = 78;
+    const TP_DOLLARID                       = 79;
+    const YY_NO_ACTION = 592;
+    const YY_ACCEPT_ACTION = 591;
+    const YY_ERROR_ACTION = 590;
+
+    const YY_SZ_ACTTAB = 2562;
+static public $yy_action = array(
+ /*     0 */   218,  317,  318,  320,  319,  316,  315,  311,  310,  312,
+ /*    10 */   313,  314,  321,  322,  197,  193,  187,   43,  591,   95,
+ /*    20 */   255,  318,  320,    6,  107,  292,   38,   11,   42,  154,
+ /*    30 */   283,   13,  181,  245,  295,  241,  262,  284,   51,   50,
+ /*    40 */    52,   44,   23,   28,  367,  374,   33,   32,  375,  383,
+ /*    50 */    21,   31,  328,  323,  325,  326,  324,    9,   36,  353,
+ /*    60 */   265,  197,  331,  329,  384,  385,  386,  382,  381,  377,
+ /*    70 */   376,  378,  379,  282,  380,  362,  218,  344,    4,  106,
+ /*    80 */   175,  120,    7,   11,   82,  129,  283,   12,  456,  292,
+ /*    90 */   453,   27,  291,  301,  361,  109,  387,  236,  368,  365,
+ /*   100 */   456,  343,  453,  243,   42,  136,  200,   37,    7,  267,
+ /*   110 */     7,  219,  256,    7,   51,   50,   52,   44,   23,   28,
+ /*   120 */   367,  374,   33,   32,  375,  383,   21,   31,  239,   99,
+ /*   130 */   171,  136,   36,  136,  261,   26,  136,  123,  373,  292,
+ /*   140 */   384,  385,  386,  382,  381,  377,  376,  378,  379,  282,
+ /*   150 */   380,  362,  218,  344,  369,  218,  200,  132,  158,  184,
+ /*   160 */    68,  119,  235,   11,   11,  153,  283,  283,  337,  301,
+ /*   170 */   361,  458,  306,  236,  368,  365,   42,  343,  252,  284,
+ /*   180 */    42,  191,  218,  458,  250,   11,  200,  287,  283,   12,
+ /*   190 */    51,   50,   52,   44,   23,   28,  367,  374,   33,   32,
+ /*   200 */   375,  383,   21,   31,  302,  108,  168,   49,  200,  232,
+ /*   210 */    11,  218,   35,  283,  240,  292,  384,  385,  386,  382,
+ /*   220 */   381,  377,  376,  378,  379,  282,  380,  362,  218,  344,
+ /*   230 */   207,  218,  200,  132,   49,    8,   54,  119,  142,   11,
+ /*   240 */    14,  158,  283,  110,  342,  301,  361,  455,  152,  236,
+ /*   250 */   368,  365,   42,  343,  231,  239,   42,  350,  103,  455,
+ /*   260 */   248,  199,  339,   49,  343,  345,   51,   50,   52,   44,
+ /*   270 */    23,   28,  367,  374,   33,   32,  375,  383,   21,   31,
+ /*   280 */   128,  183,  174,   49,  370,  163,  198,  339,   15,  158,
+ /*   290 */   292,  292,  384,  385,  386,  382,  381,  377,  376,  378,
+ /*   300 */   379,  282,  380,  362,  218,  344,  192,  218,  201,  120,
+ /*   310 */   344,  272,   82,  129,  156,  164,  270,  218,  129,  158,
+ /*   320 */   273,  301,  361,  458,  292,  236,  368,  365,  128,  343,
+ /*   330 */   236,  368,  365,  296,  343,  458,  284,  244,  130,  227,
+ /*   340 */   260,  330,   51,   50,   52,   44,   23,   28,  367,  374,
+ /*   350 */    33,   32,  375,  383,   21,   31,  207,  196,  339,   49,
+ /*   360 */    41,    8,  127,  162,  251,  229,  212,  242,  384,  385,
+ /*   370 */   386,  382,  381,  377,  376,  378,  379,  282,  380,  362,
+ /*   380 */   218,  344,  101,  218,  176,  132,  344,  140,   78,  129,
+ /*   390 */   148,  166,  249,  292,  129,  186,  278,  301,  361,  327,
+ /*   400 */   292,  236,  368,  365,  292,  343,  236,  368,  365,    5,
+ /*   410 */   343,   42,  211,   36,  121,  281,  284,  201,   51,   50,
+ /*   420 */    52,   44,   23,   28,  367,  374,   33,   32,  375,  383,
+ /*   430 */    21,   31,  218,  178,    7,   49,  179,  275,  225,  185,
+ /*   440 */    11,  284,  292,  283,  384,  385,  386,  382,  381,  377,
+ /*   450 */   376,  378,  379,  282,  380,  362,   17,  136,   11,  201,
+ /*   460 */   170,  226,  173,  200,  284,  141,  247,  223,  335,  292,
+ /*   470 */    51,   50,   52,   44,   23,   28,  367,  374,   33,   32,
+ /*   480 */   375,  383,   21,   31,  135,  218,  201,  359,   11,   11,
+ /*   490 */    11,  238,  213,  234,  188,  302,  384,  385,  386,  382,
+ /*   500 */   381,  377,  376,  378,  379,  282,  380,  362,  195,  351,
+ /*   510 */   189,  366,  251,  235,  218,  251,  264,  333,  146,  332,
+ /*   520 */   305,  200,  143,   51,   50,   52,   44,   23,   28,  367,
+ /*   530 */   374,   33,   32,  375,  383,   21,   31,  218,  203,  137,
+ /*   540 */    15,  297,   42,  271,  194,   19,   98,  116,  102,  384,
+ /*   550 */   385,  386,  382,  381,  377,  376,  378,  379,  282,  380,
+ /*   560 */   362,  372,  372,  372,  300,   34,  224,  138,   39,  139,
+ /*   570 */   225,  146,  131,  133,  159,   51,   50,   52,   44,   23,
+ /*   580 */    28,  367,  374,   33,   32,  375,  383,   21,   31,  372,
+ /*   590 */   172,  334,   94,  299,  276,  302,    2,  371,    4,  292,
+ /*   600 */   125,  384,  385,  386,  382,  381,  377,  376,  378,  379,
+ /*   610 */   282,  380,  362,  218,  344,  372,  218,  308,  132,  344,
+ /*   620 */   287,   78,  129,  150,  370,  201,  161,  129,  160,  204,
+ /*   630 */   301,  361,  341,   29,  236,  368,  365,  292,  343,  236,
+ /*   640 */   368,  365,  218,  343,  284,  216,   42,   20,  277,  284,
+ /*   650 */   263,   51,   50,   52,   44,   23,   28,  367,  374,   33,
+ /*   660 */    32,  375,  383,   21,   31,  218,  228,   45,   49,   16,
+ /*   670 */   326,  249,  104,  326,  326,  118,  105,  384,  385,  386,
+ /*   680 */   382,  381,  377,  376,  378,  379,  282,  380,  362,  340,
+ /*   690 */   372,  372,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*   700 */   326,   42,  237,   51,   50,   52,   44,   23,   28,  367,
+ /*   710 */   374,   33,   32,  375,  383,   21,   31,  218,  326,  326,
+ /*   720 */   326,  326,  326,  326,  326,  326,  114,  326,  218,  384,
+ /*   730 */   385,  386,  382,  381,  377,  376,  378,  379,  282,  380,
+ /*   740 */   362,  372,  353,  326,  307,  326,  326,  326,  326,  326,
+ /*   750 */   326,  326,  326,  326,  268,   51,   50,   52,   44,   23,
+ /*   760 */    28,  367,  374,   33,   32,  375,  383,   21,   31,  218,
+ /*   770 */   326,  326,  326,  326,  326,  326,  326,  326,   97,  355,
+ /*   780 */   112,  384,  385,  386,  382,  381,  377,  376,  378,  379,
+ /*   790 */   282,  380,  362,  372,  326,  372,  326,   42,  326,  326,
+ /*   800 */   326,  326,  326,  326,  326,  326,  158,   51,   50,   52,
+ /*   810 */    44,   23,   28,  367,  374,   33,   32,  375,  383,   21,
+ /*   820 */    31,  218,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*   830 */   326,  326,  326,  384,  385,  386,  382,  381,  377,  376,
+ /*   840 */   378,  379,  282,  380,  362,  128,  326,  326,  326,  326,
+ /*   850 */   326,  326,  326,  326,  326,  326,  326,  326,  326,   51,
+ /*   860 */    50,   52,   44,   23,   28,  367,  374,   33,   32,  375,
+ /*   870 */   383,   21,   31,  326,  326,  326,  326,  326,  326,  326,
+ /*   880 */   326,  326,  326,  326,  266,  384,  385,  386,  382,  381,
+ /*   890 */   377,  376,  378,  379,  282,  380,  362,  218,  326,  326,
+ /*   900 */   326,  326,  190,  344,  326,  326,   11,  145,  354,  283,
+ /*   910 */   288,  129,  218,  202,   18,   24,   22,  218,   45,   42,
+ /*   920 */     6,  107,   42,  236,  368,  365,  154,  343,  286,  200,
+ /*   930 */   245,  295,  241,  285,  326,   51,   50,   52,   44,   23,
+ /*   940 */    28,  367,  374,   33,   32,  375,  383,   21,   31,  218,
+ /*   950 */    10,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*   960 */   326,  384,  385,  386,  382,  381,  377,  376,  378,  379,
+ /*   970 */   282,  380,  362,  326,  326,  356,   40,  352,  326,  326,
+ /*   980 */   326,  326,  326,  326,  326,  326,  326,   51,   50,   52,
+ /*   990 */    44,   23,   28,  367,  374,   33,   32,  375,  383,   21,
+ /*  1000 */    31,  218,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1010 */   326,  326,  326,  384,  385,  386,  382,  381,  377,  376,
+ /*  1020 */   378,  379,  282,  380,  362,  326,  326,  326,  326,  326,
+ /*  1030 */   326,  326,  326,  326,  326,  326,  326,  326,  326,   51,
+ /*  1040 */    50,   52,   44,   23,   28,  367,  374,   33,   32,  375,
+ /*  1050 */   383,   21,   31,  326,  326,  326,  326,  326,  326,  326,
+ /*  1060 */   326,  326,  326,  326,  326,  384,  385,  386,  382,  381,
+ /*  1070 */   377,  376,  378,  379,  282,  380,  362,  218,  218,   51,
+ /*  1080 */    50,   52,   44,   23,   28,  367,  374,   33,   32,  375,
+ /*  1090 */   383,   21,   31,  303,  304,  326,  326,  326,  326,  326,
+ /*  1100 */   326,  326,  326,  326,  326,  384,  385,  386,  382,  381,
+ /*  1110 */   377,  376,  378,  379,  282,  380,  362,  218,  326,  218,
+ /*  1120 */   326,  326,   43,  326,  134,  208,  326,  326,    6,  107,
+ /*  1130 */   326,  326,  253,  348,  154,  452,  354,  230,  245,  295,
+ /*  1140 */   241,  246,   18,   30,   42,   42,   48,   42,    6,  107,
+ /*  1150 */   326,  326,  326,    7,  154,  326,  326,  326,  245,  295,
+ /*  1160 */   241,   47,   46,  298,  233,  363,  326,  344,  101,    1,
+ /*  1170 */   269,  155,  326,  326,  326,  129,  136,  326,   43,  326,
+ /*  1180 */   134,  220,  326,   96,    6,  107,  358,  236,  368,  365,
+ /*  1190 */   154,  343,  326,  326,  245,  295,  241,  246,   42,   30,
+ /*  1200 */   326,  254,   48,  360,   40,  352,  326,  344,  326,  326,
+ /*  1210 */   326,  151,  326,   42,  349,  129,  326,   47,   46,  298,
+ /*  1220 */   233,  363,  326,  274,  101,    1,   42,  236,  368,  365,
+ /*  1230 */   326,  343,  336,  357,   43,   42,  144,  220,  326,   96,
+ /*  1240 */     6,  107,  289,  326,   42,   42,  154,  258,  326,  294,
+ /*  1250 */   245,  295,  241,  246,   42,    3,  326,  338,   48,   42,
+ /*  1260 */   259,   42,  326,  344,  326,  326,  326,  149,  326,   42,
+ /*  1270 */   279,  129,   42,   47,   46,  298,  233,  363,  326,  293,
+ /*  1280 */   101,    1,   42,  236,  368,  365,  326,  343,  309,  347,
+ /*  1290 */    43,   42,  126,  220,  326,   96,    6,  107,  290,  326,
+ /*  1300 */    42,   42,  154,  346,  326,  257,  245,  295,  241,  246,
+ /*  1310 */    42,   30,  326,  326,   48,   42,  326,   42,  326,  326,
+ /*  1320 */   326,  326,  326,  326,  326,  326,  326,  326,  326,   47,
+ /*  1330 */    46,  298,  233,  363,  326,  326,  101,    1,  326,  326,
+ /*  1340 */   326,  326,  326,  326,  326,  326,   43,  326,  130,  220,
+ /*  1350 */   326,   96,    6,  107,  326,  326,  326,  326,  154,  326,
+ /*  1360 */   326,  326,  245,  295,  241,  246,  326,   25,  326,  326,
+ /*  1370 */    48,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1380 */   326,  326,  326,  326,  326,   47,   46,  298,  233,  363,
+ /*  1390 */   326,  326,  101,    1,  326,  326,  326,  326,  326,  326,
+ /*  1400 */   326,  326,   43,  326,  134,  210,  326,   96,    6,  107,
+ /*  1410 */   326,  326,  326,  326,  154,  326,  326,  326,  245,  295,
+ /*  1420 */   241,  246,  326,   30,  326,  326,   48,  326,  326,  326,
+ /*  1430 */   326,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1440 */   326,   47,   46,  298,  233,  363,  326,  326,  101,    1,
+ /*  1450 */   326,  326,  326,  326,  326,  326,  326,  326,   43,  326,
+ /*  1460 */   124,   92,  326,   96,    6,  107,  326,  326,  326,  326,
+ /*  1470 */   154,  326,  326,  326,  245,  295,  241,  246,  326,   30,
+ /*  1480 */   326,  326,   48,  326,  326,  326,  326,  326,  326,  326,
+ /*  1490 */   326,  326,  326,  326,  326,  326,  326,   47,   46,  298,
+ /*  1500 */   233,  363,  326,  326,  101,    1,  326,  326,  326,  326,
+ /*  1510 */   326,  326,  326,  326,   43,  326,  134,  206,  326,   96,
+ /*  1520 */     6,  107,  326,  326,  326,  326,  154,  326,  326,  326,
+ /*  1530 */   245,  295,  241,  222,  326,   30,  326,  326,   48,  326,
+ /*  1540 */   326,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1550 */   326,  326,  326,   47,   46,  298,  233,  363,  326,  326,
+ /*  1560 */   101,    1,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1570 */    43,  326,  134,  205,  326,   96,    6,  107,  326,  326,
+ /*  1580 */   326,  326,  154,  326,  326,  326,  245,  295,  241,  246,
+ /*  1590 */   326,   30,  326,  326,   48,  326,  326,  326,  326,  326,
+ /*  1600 */   326,  326,  326,  326,  326,  326,  326,  326,  326,   47,
+ /*  1610 */    46,  298,  233,  363,  326,  326,  101,    1,  326,  326,
+ /*  1620 */   326,  326,  326,  326,  326,  326,   43,  326,  134,  209,
+ /*  1630 */   326,   96,    6,  107,  326,  326,  326,  326,  154,  326,
+ /*  1640 */   326,  326,  245,  295,  241,  246,  326,   30,  326,  326,
+ /*  1650 */    48,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  1660 */   326,  326,  326,  326,  326,   47,   46,  298,  233,  363,
+ /*  1670 */   326,  326,  101,    1,  326,  326,  326,  326,  326,  326,
+ /*  1680 */   326,  326,   43,  326,  130,  220,  326,   96,    6,  107,
+ /*  1690 */   326,  326,  326,  326,  154,  326,  326,  326,  245,  295,
+ /*  1700 */   241,  246,  326,   25,  326,  326,   48,  326,  326,  326,
+ /*  1710 */   326,  326,  326,  326,  326,  326,  326,  326,  326,  190,
+ /*  1720 */   165,   47,   46,  298,  233,  363,  326,  326,  101,  292,
+ /*  1730 */   326,  326,   24,   22,  326,  326,  326,  326,   43,  326,
+ /*  1740 */   130,  221,  326,   96,    6,  107,  200,  326,  326,  326,
+ /*  1750 */   154,  326,  326,  326,  245,  295,  241,  246,  326,   25,
+ /*  1760 */   326,  326,   48,  326,  326,  326,  326,  326,  326,  326,
+ /*  1770 */   326,  326,  326,  326,  326,  326,  326,   47,   46,  298,
+ /*  1780 */   233,  363,  326,  326,  101,  326,  326,  326,  326,  326,
+ /*  1790 */   326,  326,  326,  326,  326,  501,  190,  180,  326,   96,
+ /*  1800 */   326,  326,  501,  326,  501,  501,  292,  501,  501,   24,
+ /*  1810 */    22,  326,  326,  344,  501,    7,  501,  132,  326,  326,
+ /*  1820 */    78,  129,  326,  200,  326,  326,  326,  326,  326,  301,
+ /*  1830 */   361,  501,  326,  236,  368,  365,  326,  343,  136,  326,
+ /*  1840 */   326,  344,  501,  326,  217,   93,  326,  326,   59,  117,
+ /*  1850 */   326,  326,  326,  326,  326,  326,  501,  301,  361,  326,
+ /*  1860 */   326,  236,  368,  365,  344,  343,  326,  326,  132,  326,
+ /*  1870 */   326,   77,  129,  326,  326,  326,  326,  326,  326,  326,
+ /*  1880 */   301,  361,  326,  326,  236,  368,  365,  344,  343,  326,
+ /*  1890 */   326,  132,  326,  326,   84,  129,  326,  326,  344,  326,
+ /*  1900 */   326,  326,  115,  301,  361,   72,  129,  236,  368,  365,
+ /*  1910 */   326,  343,  326,  326,  301,  361,  326,  326,  236,  368,
+ /*  1920 */   365,  326,  343,  344,  326,  326,  326,  132,  326,  326,
+ /*  1930 */    64,  129,  326,  326,  344,  326,  326,  326,  132,  301,
+ /*  1940 */   361,   66,  129,  236,  368,  365,  326,  343,  326,  326,
+ /*  1950 */   301,  361,  326,  344,  236,  368,  365,  132,  343,  326,
+ /*  1960 */    68,  129,  326,  326,  326,  326,  326,  326,  326,  301,
+ /*  1970 */   361,  326,  344,  236,  368,  365,  132,  343,  326,   76,
+ /*  1980 */   129,  326,  326,  344,  326,  326,  326,  132,  301,  361,
+ /*  1990 */    80,  129,  236,  368,  365,  326,  343,  326,  326,  301,
+ /*  2000 */   361,  326,  326,  236,  368,  365,  326,  343,  344,  326,
+ /*  2010 */   326,  326,  132,  326,  326,   60,  129,  326,  326,  344,
+ /*  2020 */   326,  326,  326,  132,  301,  361,   73,  129,  236,  368,
+ /*  2030 */   365,  326,  343,  326,  326,  301,  361,  326,  344,  236,
+ /*  2040 */   368,  365,  132,  343,  326,   74,  129,  326,  326,  326,
+ /*  2050 */   326,  326,  326,  326,  301,  361,  326,  344,  236,  368,
+ /*  2060 */   365,  132,  343,  326,   90,  129,  326,  326,  344,  326,
+ /*  2070 */   326,  326,  132,  301,  361,   65,  129,  236,  368,  365,
+ /*  2080 */   326,  343,  326,  326,  301,  361,  326,  326,  236,  368,
+ /*  2090 */   365,  326,  343,  344,  326,  326,  326,  132,  326,  326,
+ /*  2100 */    83,  129,  326,  326,  344,  326,  326,  326,   93,  301,
+ /*  2110 */   361,   53,  117,  236,  368,  365,  326,  343,  326,  326,
+ /*  2120 */   301,  361,  326,  344,  215,  368,  365,  132,  343,  326,
+ /*  2130 */    87,  129,  326,  326,  326,  326,  326,  326,  326,  301,
+ /*  2140 */   361,  326,  344,  236,  368,  365,  132,  343,  326,   58,
+ /*  2150 */   129,  326,  326,  344,  326,  326,  326,  122,  301,  361,
+ /*  2160 */    55,  129,  236,  368,  365,  326,  343,  326,  326,  301,
+ /*  2170 */   361,  326,  326,  236,  368,  365,  326,  343,  344,  326,
+ /*  2180 */   326,  326,  132,  326,  326,   70,  129,  326,  326,  344,
+ /*  2190 */   326,  326,  326,  132,  301,  361,   91,  129,  236,  368,
+ /*  2200 */   365,  326,  343,  326,  326,  301,  361,  326,  344,  236,
+ /*  2210 */   368,  365,  111,  343,  326,   63,  129,  326,  326,  326,
+ /*  2220 */   326,  326,  326,  326,  301,  361,  326,  344,  236,  368,
+ /*  2230 */   365,  132,  343,  326,   86,  129,  326,  326,  344,  326,
+ /*  2240 */   326,  326,  132,  301,  361,   79,  129,  236,  368,  365,
+ /*  2250 */   326,  343,  326,  326,  301,  361,  326,  326,  236,  368,
+ /*  2260 */   365,  326,  343,  344,  326,  326,  326,  132,  326,  326,
+ /*  2270 */    75,  129,  326,  326,  344,  326,  326,  326,  132,  301,
+ /*  2280 */   361,   88,  129,  236,  368,  365,  326,  343,  326,  326,
+ /*  2290 */   301,  361,  326,  344,  236,  368,  365,  132,  343,  326,
+ /*  2300 */    62,  129,  326,  326,  326,  326,  326,  326,  326,  301,
+ /*  2310 */   361,  326,  344,  236,  368,  365,  132,  343,  326,   61,
+ /*  2320 */   129,  326,  326,  344,  326,  326,  326,  132,  301,  361,
+ /*  2330 */    69,  129,  236,  368,  365,  326,  343,  326,  326,  301,
+ /*  2340 */   361,  326,  326,  236,  368,  365,  326,  343,  344,  326,
+ /*  2350 */   326,  326,  132,  326,  326,   57,  129,  326,  326,  344,
+ /*  2360 */   326,  326,  326,  132,  301,  361,   89,  129,  236,  368,
+ /*  2370 */   365,  326,  343,  326,  326,  301,  361,  326,  344,  236,
+ /*  2380 */   368,  365,  132,  343,  326,   81,  129,  326,  326,  326,
+ /*  2390 */   326,  326,  326,  326,  301,  361,  326,  344,  236,  368,
+ /*  2400 */   365,  113,  343,  326,   85,  129,  326,  326,  344,  326,
+ /*  2410 */   326,  326,  132,  301,  361,   71,  129,  236,  368,  365,
+ /*  2420 */   326,  343,  326,  326,  301,  361,  326,  326,  236,  368,
+ /*  2430 */   365,  326,  343,  344,  326,  326,  326,  132,  326,  326,
+ /*  2440 */    67,  129,  326,  326,  344,  326,  326,  326,  132,  301,
+ /*  2450 */   361,   56,  129,  214,  368,  365,  326,  343,  326,  326,
+ /*  2460 */   301,  361,  326,  344,  236,  368,  365,  147,  343,  326,
+ /*  2470 */   326,  129,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  2480 */   364,  326,  344,  236,  368,  365,  157,  343,  326,  326,
+ /*  2490 */   129,  326,  326,  326,  326,  100,  177,  326,  326,  280,
+ /*  2500 */   326,  326,  236,  368,  365,  292,  343,  326,   24,   22,
+ /*  2510 */   326,  190,  167,  326,  326,  326,  326,  326,  190,  182,
+ /*  2520 */   326,  292,  200,  326,   24,   22,  326,  326,  292,  326,
+ /*  2530 */   326,   24,   22,  326,  190,  169,  326,  326,  200,  326,
+ /*  2540 */   326,  326,  326,  326,  292,  200,  326,   24,   22,  326,
+ /*  2550 */   326,  326,  326,  326,  326,  326,  326,  326,  326,  326,
+ /*  2560 */   326,  200,
+    );
+    static public $yy_lookahead = array(
+ /*     0 */     1,   83,   84,   85,    3,    4,    5,    6,    7,    8,
+ /*    10 */     9,   10,   11,   12,   13,   98,   90,   16,   81,   82,
+ /*    20 */    83,   84,   85,   22,   23,   99,   27,   16,   29,   28,
+ /*    30 */    19,   20,  109,   32,   33,   34,   25,  111,   39,   40,
+ /*    40 */    41,   42,   43,   44,   45,   46,   47,   48,   49,   50,
+ /*    50 */    51,   52,    4,    5,    6,    7,    8,   16,   36,   84,
+ /*    60 */    38,   13,   14,   15,   65,   66,   67,   68,   69,   70,
+ /*    70 */    71,   72,   73,   74,   75,   76,    1,   84,   37,   89,
+ /*    80 */    90,   88,   37,   16,   91,   92,   19,   20,   17,   99,
+ /*    90 */    17,   20,   17,  100,  101,  120,  121,  104,  105,  106,
+ /*   100 */    29,  108,   29,   58,   29,   60,  116,   31,   37,   64,
+ /*   110 */    37,  118,  119,   37,   39,   40,   41,   42,   43,   44,
+ /*   120 */    45,   46,   47,   48,   49,   50,   51,   52,   61,   89,
+ /*   130 */    90,   60,   36,   60,   38,   16,   60,   18,   19,   99,
+ /*   140 */    65,   66,   67,   68,   69,   70,   71,   72,   73,   74,
+ /*   150 */    75,   76,    1,   84,   35,    1,  116,   88,   21,   89,
+ /*   160 */    91,   92,   93,   16,   16,   97,   19,   19,   17,  100,
+ /*   170 */   101,   17,   19,  104,  105,  106,   29,  108,   31,  111,
+ /*   180 */    29,   89,    1,   29,   30,   16,  116,  117,   19,   20,
+ /*   190 */    39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
+ /*   200 */    49,   50,   51,   52,   25,   89,   90,   53,  116,   61,
+ /*   210 */    16,    1,   31,   19,   61,   99,   65,   66,   67,   68,
+ /*   220 */    69,   70,   71,   72,   73,   74,   75,   76,    1,   84,
+ /*   230 */    58,    1,  116,   88,   53,   63,   91,   92,   93,   16,
+ /*   240 */    20,   21,   19,   86,   17,  100,  101,   17,   92,  104,
+ /*   250 */   105,  106,   29,  108,   31,   61,   29,   78,   98,   29,
+ /*   260 */   104,  112,  113,   53,  108,  113,   39,   40,   41,   42,
+ /*   270 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   280 */    60,   90,   90,   53,  110,  109,  112,  113,   20,   21,
+ /*   290 */    99,   99,   65,   66,   67,   68,   69,   70,   71,   72,
+ /*   300 */    73,   74,   75,   76,    1,   84,   98,    1,  116,   88,
+ /*   310 */    84,   62,   91,   92,   88,   90,   64,    1,   92,   21,
+ /*   320 */    17,  100,  101,   17,   99,  104,  105,  106,   60,  108,
+ /*   330 */   104,  105,  106,   17,  108,   29,  111,   21,   18,   19,
+ /*   340 */   119,   14,   39,   40,   41,   42,   43,   44,   45,   46,
+ /*   350 */    47,   48,   49,   50,   51,   52,   58,  112,  113,   53,
+ /*   360 */    16,   63,   18,   19,   92,   93,   94,   19,   65,   66,
+ /*   370 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
+ /*   380 */     1,   84,   62,    1,   90,   88,   84,   19,   91,   92,
+ /*   390 */    88,   90,   58,   99,   92,   90,   17,  100,  101,   17,
+ /*   400 */    99,  104,  105,  106,   99,  108,  104,  105,  106,   36,
+ /*   410 */   108,   29,  115,   36,   19,   38,  111,  116,   39,   40,
+ /*   420 */    41,   42,   43,   44,   45,   46,   47,   48,   49,   50,
+ /*   430 */    51,   52,    1,   90,   37,   53,   89,   64,    2,  109,
+ /*   440 */    16,  111,   99,   19,   65,   66,   67,   68,   69,   70,
+ /*   450 */    71,   72,   73,   74,   75,   76,   20,   60,   16,  116,
+ /*   460 */    90,   19,  109,  116,  111,   18,   18,   19,   19,   99,
+ /*   470 */    39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
+ /*   480 */    49,   50,   51,   52,   37,    1,  116,   17,   16,   16,
+ /*   490 */    16,   19,   19,   19,   89,   25,   65,   66,   67,   68,
+ /*   500 */    69,   70,   71,   72,   73,   74,   75,   76,   24,   78,
+ /*   510 */    24,  107,   92,   93,    1,   92,   93,   85,  114,   87,
+ /*   520 */    19,  116,   36,   39,   40,   41,   42,   43,   44,   45,
+ /*   530 */    46,   47,   48,   49,   50,   51,   52,    1,   19,   18,
+ /*   540 */    20,   35,   29,   62,   19,    2,   96,   96,   96,   65,
+ /*   550 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
+ /*   560 */    76,  111,  111,  111,  107,   54,   30,   18,   26,   18,
+ /*   570 */     2,  114,   18,   18,   96,   39,   40,   41,   42,   43,
+ /*   580 */    44,   45,   46,   47,   48,   49,   50,   51,   52,  111,
+ /*   590 */    90,   19,   19,   35,   38,   25,   37,   19,   37,   99,
+ /*   600 */    96,   65,   66,   67,   68,   69,   70,   71,   72,   73,
+ /*   610 */    74,   75,   76,    1,   84,  111,    1,   99,   88,   84,
+ /*   620 */   117,   91,   92,   88,  110,  116,  109,   92,   90,   17,
+ /*   630 */   100,  101,   17,   20,  104,  105,  106,   99,  108,  104,
+ /*   640 */   105,  106,    1,  108,  111,  115,   29,   29,  114,  111,
+ /*   650 */    29,   39,   40,   41,   42,   43,   44,   45,   46,   47,
+ /*   660 */    48,   49,   50,   51,   52,    1,   95,    2,   53,   95,
+ /*   670 */   122,   58,  109,  122,  122,   96,   96,   65,   66,   67,
+ /*   680 */    68,   69,   70,   71,   72,   73,   74,   75,   76,   17,
+ /*   690 */   111,  111,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*   700 */   122,   29,   38,   39,   40,   41,   42,   43,   44,   45,
+ /*   710 */    46,   47,   48,   49,   50,   51,   52,    1,  122,  122,
+ /*   720 */   122,  122,  122,  122,  122,  122,   96,  122,    1,   65,
+ /*   730 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
+ /*   740 */    76,  111,   84,  122,   17,  122,  122,  122,  122,  122,
+ /*   750 */   122,  122,  122,  122,   38,   39,   40,   41,   42,   43,
+ /*   760 */    44,   45,   46,   47,   48,   49,   50,   51,   52,    1,
+ /*   770 */   122,  122,  122,  122,  122,  122,  122,  122,   96,  121,
+ /*   780 */    96,   65,   66,   67,   68,   69,   70,   71,   72,   73,
+ /*   790 */    74,   75,   76,  111,  122,  111,  122,   29,  122,  122,
+ /*   800 */   122,  122,  122,  122,  122,  122,   21,   39,   40,   41,
+ /*   810 */    42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+ /*   820 */    52,    1,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*   830 */   122,  122,  122,   65,   66,   67,   68,   69,   70,   71,
+ /*   840 */    72,   73,   74,   75,   76,   60,  122,  122,  122,  122,
+ /*   850 */   122,  122,  122,  122,  122,  122,  122,  122,  122,   39,
+ /*   860 */    40,   41,   42,   43,   44,   45,   46,   47,   48,   49,
+ /*   870 */    50,   51,   52,  122,  122,  122,  122,  122,  122,  122,
+ /*   880 */   122,  122,  122,  122,   64,   65,   66,   67,   68,   69,
+ /*   890 */    70,   71,   72,   73,   74,   75,   76,    1,  122,  122,
+ /*   900 */   122,  122,   89,   84,  122,  122,   16,   88,   10,   19,
+ /*   910 */    17,   92,    1,   17,   16,  102,  103,    1,    2,   29,
+ /*   920 */    22,   23,   29,  104,  105,  106,   28,  108,   17,  116,
+ /*   930 */    32,   33,   34,   17,  122,   39,   40,   41,   42,   43,
+ /*   940 */    44,   45,   46,   47,   48,   49,   50,   51,   52,    1,
+ /*   950 */     2,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*   960 */   122,   65,   66,   67,   68,   69,   70,   71,   72,   73,
+ /*   970 */    74,   75,   76,  122,  122,   77,   78,   79,  122,  122,
+ /*   980 */   122,  122,  122,  122,  122,  122,  122,   39,   40,   41,
+ /*   990 */    42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+ /*  1000 */    52,    1,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1010 */   122,  122,  122,   65,   66,   67,   68,   69,   70,   71,
+ /*  1020 */    72,   73,   74,   75,   76,  122,  122,  122,  122,  122,
+ /*  1030 */   122,  122,  122,  122,  122,  122,  122,  122,  122,   39,
+ /*  1040 */    40,   41,   42,   43,   44,   45,   46,   47,   48,   49,
+ /*  1050 */    50,   51,   52,  122,  122,  122,  122,  122,  122,  122,
+ /*  1060 */   122,  122,  122,  122,  122,   65,   66,   67,   68,   69,
+ /*  1070 */    70,   71,   72,   73,   74,   75,   76,    1,    1,   39,
+ /*  1080 */    40,   41,   42,   43,   44,   45,   46,   47,   48,   49,
+ /*  1090 */    50,   51,   52,   17,   17,  122,  122,  122,  122,  122,
+ /*  1100 */   122,  122,  122,  122,  122,   65,   66,   67,   68,   69,
+ /*  1110 */    70,   71,   72,   73,   74,   75,   76,    1,  122,    1,
+ /*  1120 */   122,  122,   16,  122,   18,   19,  122,  122,   22,   23,
+ /*  1130 */   122,  122,   17,   17,   28,   17,   10,   21,   32,   33,
+ /*  1140 */    34,   35,   16,   37,   29,   29,   40,   29,   22,   23,
+ /*  1150 */   122,  122,  122,   37,   28,  122,  122,  122,   32,   33,
+ /*  1160 */    34,   55,   56,   57,   58,   59,  122,   84,   62,   63,
+ /*  1170 */    64,   88,  122,  122,  122,   92,   60,  122,   16,  122,
+ /*  1180 */    18,   19,  122,   77,   22,   23,   17,  104,  105,  106,
+ /*  1190 */    28,  108,  122,  122,   32,   33,   34,   35,   29,   37,
+ /*  1200 */   122,   17,   40,   77,   78,   79,  122,   84,  122,  122,
+ /*  1210 */   122,   88,  122,   29,   17,   92,  122,   55,   56,   57,
+ /*  1220 */    58,   59,  122,   17,   62,   63,   29,  104,  105,  106,
+ /*  1230 */   122,  108,   17,   17,   16,   29,   18,   19,  122,   77,
+ /*  1240 */    22,   23,   17,  122,   29,   29,   28,   17,  122,   17,
+ /*  1250 */    32,   33,   34,   35,   29,   37,  122,   17,   40,   29,
+ /*  1260 */    17,   29,  122,   84,  122,  122,  122,   88,  122,   29,
+ /*  1270 */    17,   92,   29,   55,   56,   57,   58,   59,  122,   17,
+ /*  1280 */    62,   63,   29,  104,  105,  106,  122,  108,   17,   17,
+ /*  1290 */    16,   29,   18,   19,  122,   77,   22,   23,   17,  122,
+ /*  1300 */    29,   29,   28,   17,  122,   17,   32,   33,   34,   35,
+ /*  1310 */    29,   37,  122,  122,   40,   29,  122,   29,  122,  122,
+ /*  1320 */   122,  122,  122,  122,  122,  122,  122,  122,  122,   55,
+ /*  1330 */    56,   57,   58,   59,  122,  122,   62,   63,  122,  122,
+ /*  1340 */   122,  122,  122,  122,  122,  122,   16,  122,   18,   19,
+ /*  1350 */   122,   77,   22,   23,  122,  122,  122,  122,   28,  122,
+ /*  1360 */   122,  122,   32,   33,   34,   35,  122,   37,  122,  122,
+ /*  1370 */    40,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1380 */   122,  122,  122,  122,  122,   55,   56,   57,   58,   59,
+ /*  1390 */   122,  122,   62,   63,  122,  122,  122,  122,  122,  122,
+ /*  1400 */   122,  122,   16,  122,   18,   19,  122,   77,   22,   23,
+ /*  1410 */   122,  122,  122,  122,   28,  122,  122,  122,   32,   33,
+ /*  1420 */    34,   35,  122,   37,  122,  122,   40,  122,  122,  122,
+ /*  1430 */   122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1440 */   122,   55,   56,   57,   58,   59,  122,  122,   62,   63,
+ /*  1450 */   122,  122,  122,  122,  122,  122,  122,  122,   16,  122,
+ /*  1460 */    18,   19,  122,   77,   22,   23,  122,  122,  122,  122,
+ /*  1470 */    28,  122,  122,  122,   32,   33,   34,   35,  122,   37,
+ /*  1480 */   122,  122,   40,  122,  122,  122,  122,  122,  122,  122,
+ /*  1490 */   122,  122,  122,  122,  122,  122,  122,   55,   56,   57,
+ /*  1500 */    58,   59,  122,  122,   62,   63,  122,  122,  122,  122,
+ /*  1510 */   122,  122,  122,  122,   16,  122,   18,   19,  122,   77,
+ /*  1520 */    22,   23,  122,  122,  122,  122,   28,  122,  122,  122,
+ /*  1530 */    32,   33,   34,   35,  122,   37,  122,  122,   40,  122,
+ /*  1540 */   122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1550 */   122,  122,  122,   55,   56,   57,   58,   59,  122,  122,
+ /*  1560 */    62,   63,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1570 */    16,  122,   18,   19,  122,   77,   22,   23,  122,  122,
+ /*  1580 */   122,  122,   28,  122,  122,  122,   32,   33,   34,   35,
+ /*  1590 */   122,   37,  122,  122,   40,  122,  122,  122,  122,  122,
+ /*  1600 */   122,  122,  122,  122,  122,  122,  122,  122,  122,   55,
+ /*  1610 */    56,   57,   58,   59,  122,  122,   62,   63,  122,  122,
+ /*  1620 */   122,  122,  122,  122,  122,  122,   16,  122,   18,   19,
+ /*  1630 */   122,   77,   22,   23,  122,  122,  122,  122,   28,  122,
+ /*  1640 */   122,  122,   32,   33,   34,   35,  122,   37,  122,  122,
+ /*  1650 */    40,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  1660 */   122,  122,  122,  122,  122,   55,   56,   57,   58,   59,
+ /*  1670 */   122,  122,   62,   63,  122,  122,  122,  122,  122,  122,
+ /*  1680 */   122,  122,   16,  122,   18,   19,  122,   77,   22,   23,
+ /*  1690 */   122,  122,  122,  122,   28,  122,  122,  122,   32,   33,
+ /*  1700 */    34,   35,  122,   37,  122,  122,   40,  122,  122,  122,
+ /*  1710 */   122,  122,  122,  122,  122,  122,  122,  122,  122,   89,
+ /*  1720 */    90,   55,   56,   57,   58,   59,  122,  122,   62,   99,
+ /*  1730 */   122,  122,  102,  103,  122,  122,  122,  122,   16,  122,
+ /*  1740 */    18,   19,  122,   77,   22,   23,  116,  122,  122,  122,
+ /*  1750 */    28,  122,  122,  122,   32,   33,   34,   35,  122,   37,
+ /*  1760 */   122,  122,   40,  122,  122,  122,  122,  122,  122,  122,
+ /*  1770 */   122,  122,  122,  122,  122,  122,  122,   55,   56,   57,
+ /*  1780 */    58,   59,  122,  122,   62,  122,  122,  122,  122,  122,
+ /*  1790 */   122,  122,  122,  122,  122,   17,   89,   90,  122,   77,
+ /*  1800 */   122,  122,   24,  122,   26,   27,   99,   29,   30,  102,
+ /*  1810 */   103,  122,  122,   84,   36,   37,   38,   88,  122,  122,
+ /*  1820 */    91,   92,  122,  116,  122,  122,  122,  122,  122,  100,
+ /*  1830 */   101,   53,  122,  104,  105,  106,  122,  108,   60,  122,
+ /*  1840 */   122,   84,   64,  122,  115,   88,  122,  122,   91,   92,
+ /*  1850 */   122,  122,  122,  122,  122,  122,   78,  100,  101,  122,
+ /*  1860 */   122,  104,  105,  106,   84,  108,  122,  122,   88,  122,
+ /*  1870 */   122,   91,   92,  122,  122,  122,  122,  122,  122,  122,
+ /*  1880 */   100,  101,  122,  122,  104,  105,  106,   84,  108,  122,
+ /*  1890 */   122,   88,  122,  122,   91,   92,  122,  122,   84,  122,
+ /*  1900 */   122,  122,   88,  100,  101,   91,   92,  104,  105,  106,
+ /*  1910 */   122,  108,  122,  122,  100,  101,  122,  122,  104,  105,
+ /*  1920 */   106,  122,  108,   84,  122,  122,  122,   88,  122,  122,
+ /*  1930 */    91,   92,  122,  122,   84,  122,  122,  122,   88,  100,
+ /*  1940 */   101,   91,   92,  104,  105,  106,  122,  108,  122,  122,
+ /*  1950 */   100,  101,  122,   84,  104,  105,  106,   88,  108,  122,
+ /*  1960 */    91,   92,  122,  122,  122,  122,  122,  122,  122,  100,
+ /*  1970 */   101,  122,   84,  104,  105,  106,   88,  108,  122,   91,
+ /*  1980 */    92,  122,  122,   84,  122,  122,  122,   88,  100,  101,
+ /*  1990 */    91,   92,  104,  105,  106,  122,  108,  122,  122,  100,
+ /*  2000 */   101,  122,  122,  104,  105,  106,  122,  108,   84,  122,
+ /*  2010 */   122,  122,   88,  122,  122,   91,   92,  122,  122,   84,
+ /*  2020 */   122,  122,  122,   88,  100,  101,   91,   92,  104,  105,
+ /*  2030 */   106,  122,  108,  122,  122,  100,  101,  122,   84,  104,
+ /*  2040 */   105,  106,   88,  108,  122,   91,   92,  122,  122,  122,
+ /*  2050 */   122,  122,  122,  122,  100,  101,  122,   84,  104,  105,
+ /*  2060 */   106,   88,  108,  122,   91,   92,  122,  122,   84,  122,
+ /*  2070 */   122,  122,   88,  100,  101,   91,   92,  104,  105,  106,
+ /*  2080 */   122,  108,  122,  122,  100,  101,  122,  122,  104,  105,
+ /*  2090 */   106,  122,  108,   84,  122,  122,  122,   88,  122,  122,
+ /*  2100 */    91,   92,  122,  122,   84,  122,  122,  122,   88,  100,
+ /*  2110 */   101,   91,   92,  104,  105,  106,  122,  108,  122,  122,
+ /*  2120 */   100,  101,  122,   84,  104,  105,  106,   88,  108,  122,
+ /*  2130 */    91,   92,  122,  122,  122,  122,  122,  122,  122,  100,
+ /*  2140 */   101,  122,   84,  104,  105,  106,   88,  108,  122,   91,
+ /*  2150 */    92,  122,  122,   84,  122,  122,  122,   88,  100,  101,
+ /*  2160 */    91,   92,  104,  105,  106,  122,  108,  122,  122,  100,
+ /*  2170 */   101,  122,  122,  104,  105,  106,  122,  108,   84,  122,
+ /*  2180 */   122,  122,   88,  122,  122,   91,   92,  122,  122,   84,
+ /*  2190 */   122,  122,  122,   88,  100,  101,   91,   92,  104,  105,
+ /*  2200 */   106,  122,  108,  122,  122,  100,  101,  122,   84,  104,
+ /*  2210 */   105,  106,   88,  108,  122,   91,   92,  122,  122,  122,
+ /*  2220 */   122,  122,  122,  122,  100,  101,  122,   84,  104,  105,
+ /*  2230 */   106,   88,  108,  122,   91,   92,  122,  122,   84,  122,
+ /*  2240 */   122,  122,   88,  100,  101,   91,   92,  104,  105,  106,
+ /*  2250 */   122,  108,  122,  122,  100,  101,  122,  122,  104,  105,
+ /*  2260 */   106,  122,  108,   84,  122,  122,  122,   88,  122,  122,
+ /*  2270 */    91,   92,  122,  122,   84,  122,  122,  122,   88,  100,
+ /*  2280 */   101,   91,   92,  104,  105,  106,  122,  108,  122,  122,
+ /*  2290 */   100,  101,  122,   84,  104,  105,  106,   88,  108,  122,
+ /*  2300 */    91,   92,  122,  122,  122,  122,  122,  122,  122,  100,
+ /*  2310 */   101,  122,   84,  104,  105,  106,   88,  108,  122,   91,
+ /*  2320 */    92,  122,  122,   84,  122,  122,  122,   88,  100,  101,
+ /*  2330 */    91,   92,  104,  105,  106,  122,  108,  122,  122,  100,
+ /*  2340 */   101,  122,  122,  104,  105,  106,  122,  108,   84,  122,
+ /*  2350 */   122,  122,   88,  122,  122,   91,   92,  122,  122,   84,
+ /*  2360 */   122,  122,  122,   88,  100,  101,   91,   92,  104,  105,
+ /*  2370 */   106,  122,  108,  122,  122,  100,  101,  122,   84,  104,
+ /*  2380 */   105,  106,   88,  108,  122,   91,   92,  122,  122,  122,
+ /*  2390 */   122,  122,  122,  122,  100,  101,  122,   84,  104,  105,
+ /*  2400 */   106,   88,  108,  122,   91,   92,  122,  122,   84,  122,
+ /*  2410 */   122,  122,   88,  100,  101,   91,   92,  104,  105,  106,
+ /*  2420 */   122,  108,  122,  122,  100,  101,  122,  122,  104,  105,
+ /*  2430 */   106,  122,  108,   84,  122,  122,  122,   88,  122,  122,
+ /*  2440 */    91,   92,  122,  122,   84,  122,  122,  122,   88,  100,
+ /*  2450 */   101,   91,   92,  104,  105,  106,  122,  108,  122,  122,
+ /*  2460 */   100,  101,  122,   84,  104,  105,  106,   88,  108,  122,
+ /*  2470 */   122,   92,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  2480 */   101,  122,   84,  104,  105,  106,   88,  108,  122,  122,
+ /*  2490 */    92,  122,  122,  122,  122,   89,   90,  122,  122,  101,
+ /*  2500 */   122,  122,  104,  105,  106,   99,  108,  122,  102,  103,
+ /*  2510 */   122,   89,   90,  122,  122,  122,  122,  122,   89,   90,
+ /*  2520 */   122,   99,  116,  122,  102,  103,  122,  122,   99,  122,
+ /*  2530 */   122,  102,  103,  122,   89,   90,  122,  122,  116,  122,
+ /*  2540 */   122,  122,  122,  122,   99,  116,  122,  102,  103,  122,
+ /*  2550 */   122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
+ /*  2560 */   122,  116,
+);
+    const YY_SHIFT_USE_DFLT = -2;
+    const YY_SHIFT_MAX = 252;
+    static public $yy_shift_ofst = array(
+ /*     0 */     1, 1386, 1162, 1218, 1162, 1386, 1218, 1162, 1106, 1162,
+ /*    10 */  1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1442, 1554,
+ /*    20 */  1498, 1162, 1162, 1162, 1162, 1162, 1162, 1610, 1162, 1162,
+ /*    30 */  1162, 1162, 1162, 1162, 1274, 1162, 1162, 1162, 1162, 1162,
+ /*    40 */  1162, 1162, 1498, 1442, 1330, 1330, 1666, 1666, 1666, 1722,
+ /*    50 */  1666, 1666, 1666,  227,   75,  151,   -1,  768,  768,  768,
+ /*    60 */   948,  896,  820,  536,  379,  716,  303,  431,  664,  612,
+ /*    70 */   484, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000,
+ /*    80 */  1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000,
+ /*    90 */  1040, 1040, 1116,  382,  513,    1, 1126,  147,  223, 1118,
+ /*   100 */  1118,  320,  890,  916,  298,  890,  513,  447,  513,  898,
+ /*   110 */    48,  154,   11,  306,   67,  230,  194,  220,  169,  268,
+ /*   120 */   181,  316,  615,  424,  473,  424,  472,  474,  448,  785,
+ /*   130 */   424,  424,  210,  424,  442,  447,  448,  424,  424,  424,
+ /*   140 */   727,  424, 1288,  447,  442,  641,  137,  641,  641,  641,
+ /*   150 */   641,  641,  137,  617,  618,  641,  641,   -2,  344,  148,
+ /*   160 */   893,  172,   41,  172, 1225, 1215, 1216, 1206, 1197, 1115,
+ /*   170 */  1169, 1184, 1230,  172, 1271,  672, 1262, 1272, 1286, 1077,
+ /*   180 */  1281,  172, 1240, 1232,  911,  172, 1253, 1243, 1076,  621,
+ /*   190 */   641,  641,  665,  665,  559,  621,  137,  327,  137,  137,
+ /*   200 */    -2,   -2,   -2,   -2,   -2, 1778,   71,  119,   45,   73,
+ /*   210 */    76,   96,  486,  436,  179,  470,   22,  377,  153,  373,
+ /*   220 */   397,  397,  613,  561,  554,  572,  568,  249,  549,  542,
+ /*   230 */   573,  555,  578,  558,  559,  556,  570,  511,  543,  449,
+ /*   240 */   501,  395,  252,  348,  368,  519,  334,  525,  481,  506,
+ /*   250 */   521,  520,  551,
+);
+    const YY_REDUCE_USE_DFLT = -84;
+    const YY_REDUCE_MAX = 204;
+    static public $yy_reduce_ofst = array(
+ /*     0 */   -63,   -7, 1729,   69,  297,  221,  145,  530, 2209, 2228,
+ /*    10 */  1973, 1850, 2190, 2039, 2058, 1899, 2094, 2069, 2020, 2105,
+ /*    20 */  2124, 2179, 2154, 2143, 2009, 1984, 1839, 1814, 1780, 1803,
+ /*    30 */  1869, 1888, 1954, 1935, 1924, 2275, 2324, 2294, 2264, 2360,
+ /*    40 */  2349, 2239, 2313, 1757, 2379, 2398,  226,  819,  302,  535,
+ /*    50 */  1179, 1123, 1083, 2406, 1707, 1630, 2422, 2445, 2429, 2406,
+ /*    60 */   813,  813,  813,  813,  813,  813,  813,  813,  813,  813,
+ /*    70 */   813,  813,  813,  813,  813,  813,  813,  813,  813,  813,
+ /*    80 */   813,  813,  813,  813,  813,  813,  813,  813,  813,  813,
+ /*    90 */   813,  813,  -10,   40,  116,  -82,  -25,  225,  -74,  192,
+ /*   100 */   343,  156,  305,   70,  174,  538,  370,  272,  301,  658,
+ /*   110 */   432,   92,   68,   92,  330,   92,  330,  245,  330,  245,
+ /*   120 */    92,  347,   92,  478,  451,  353,  451,  504,  404,  245,
+ /*   130 */   451,  450,   92,  452,  451,  420,  457,  682,  684,  580,
+ /*   140 */   405,  579,  500,  423,  630,   92,  149,   92,   92,   92,
+ /*   150 */    92,   92,  245,  294,  191,   92,   92,   92,  534,  533,
+ /*   160 */   518,  514,  517,  514,  518,  518,  518,  518,  518,  518,
+ /*   170 */   518,  518,  518,  514,  518,  518,  518,  518,  518,  509,
+ /*   180 */   518,  514,  518,  518,  509,  514,  518,  518,  509,  574,
+ /*   190 */   509,  509,  503,  503,  563,  571,  152,  157,  152,  152,
+ /*   200 */   -83,  208,  176,  160,  -77,
+);
+    static public $yyExpectedTokens = array(
+        /* 0 */ array(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 22, 23, 28, 32, 33, 34, ),
+        /* 1 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 2 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 3 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 4 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 5 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 6 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 7 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 8 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 64, 77, ),
+        /* 9 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 10 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 11 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 12 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 13 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 14 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 15 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 16 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 17 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 18 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 19 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 20 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 21 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 22 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 23 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 24 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 25 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 26 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 27 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 28 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 29 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 30 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 31 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 32 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 33 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 34 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 35 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 36 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 37 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 38 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 39 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 40 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 41 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 42 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 43 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 44 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 45 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 63, 77, ),
+        /* 46 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 47 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 48 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 49 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 50 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 51 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 52 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 35, 37, 40, 55, 56, 57, 58, 59, 62, 77, ),
+        /* 53 */ array(1, 17, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 54 */ array(1, 17, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 55 */ array(1, 17, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 56 */ array(1, 27, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 57 */ array(1, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 58 */ array(1, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 59 */ array(1, 29, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 60 */ array(1, 2, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 61 */ array(1, 17, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 62 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 63 */ array(1, 30, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 64 */ array(1, 17, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 65 */ array(1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 66 */ array(1, 17, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 67 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, ),
+        /* 68 */ array(1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 69 */ array(1, 17, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 70 */ array(1, 24, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 71 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 72 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 73 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 74 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 75 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 76 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 77 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 78 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 79 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 80 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 81 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 82 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 83 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 84 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 85 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 86 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 87 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 88 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 89 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 90 */ array(39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 91 */ array(39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, ),
+        /* 92 */ array(1, 17, 21, 29, 37, 60, ),
+        /* 93 */ array(1, 17, 29, 53, ),
+        /* 94 */ array(1, 29, ),
+        /* 95 */ array(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 22, 23, 28, 32, 33, 34, ),
+        /* 96 */ array(10, 16, 22, 23, 28, 32, 33, 34, 77, 78, 79, ),
+        /* 97 */ array(16, 19, 29, 31, ),
+        /* 98 */ array(16, 19, 29, 31, ),
+        /* 99 */ array(1, 17, 29, ),
+        /* 100 */ array(1, 17, 29, ),
+        /* 101 */ array(18, 19, 62, ),
+        /* 102 */ array(16, 19, 29, ),
+        /* 103 */ array(1, 2, 17, ),
+        /* 104 */ array(21, 58, 63, ),
+        /* 105 */ array(16, 19, 29, ),
+        /* 106 */ array(1, 29, ),
+        /* 107 */ array(18, 37, ),
+        /* 108 */ array(1, 29, ),
+        /* 109 */ array(10, 16, 22, 23, 28, 32, 33, 34, 77, 78, 79, ),
+        /* 110 */ array(4, 5, 6, 7, 8, 13, 14, 15, ),
+        /* 111 */ array(1, 17, 29, 30, 53, ),
+        /* 112 */ array(16, 19, 20, 25, ),
+        /* 113 */ array(1, 17, 29, 53, ),
+        /* 114 */ array(16, 19, 20, 61, ),
+        /* 115 */ array(1, 17, 29, 53, ),
+        /* 116 */ array(16, 19, 61, ),
+        /* 117 */ array(20, 21, 60, ),
+        /* 118 */ array(16, 19, 20, ),
+        /* 119 */ array(20, 21, 60, ),
+        /* 120 */ array(1, 31, 53, ),
+        /* 121 */ array(1, 17, 21, ),
+        /* 122 */ array(1, 17, 53, ),
+        /* 123 */ array(16, 19, ),
+        /* 124 */ array(16, 19, ),
+        /* 125 */ array(16, 19, ),
+        /* 126 */ array(16, 19, ),
+        /* 127 */ array(16, 19, ),
+        /* 128 */ array(18, 19, ),
+        /* 129 */ array(21, 60, ),
+        /* 130 */ array(16, 19, ),
+        /* 131 */ array(16, 19, ),
+        /* 132 */ array(1, 53, ),
+        /* 133 */ array(16, 19, ),
+        /* 134 */ array(16, 19, ),
+        /* 135 */ array(18, 37, ),
+        /* 136 */ array(18, 19, ),
+        /* 137 */ array(16, 19, ),
+        /* 138 */ array(16, 19, ),
+        /* 139 */ array(16, 19, ),
+        /* 140 */ array(1, 17, ),
+        /* 141 */ array(16, 19, ),
+        /* 142 */ array(17, 29, ),
+        /* 143 */ array(18, 37, ),
+        /* 144 */ array(16, 19, ),
+        /* 145 */ array(1, ),
+        /* 146 */ array(21, ),
+        /* 147 */ array(1, ),
+        /* 148 */ array(1, ),
+        /* 149 */ array(1, ),
+        /* 150 */ array(1, ),
+        /* 151 */ array(1, ),
+        /* 152 */ array(21, ),
+        /* 153 */ array(29, ),
+        /* 154 */ array(29, ),
+        /* 155 */ array(1, ),
+        /* 156 */ array(1, ),
+        /* 157 */ array(),
+        /* 158 */ array(16, 18, 19, ),
+        /* 159 */ array(16, 19, 61, ),
+        /* 160 */ array(17, 29, ),
+        /* 161 */ array(58, 63, ),
+        /* 162 */ array(16, 37, ),
+        /* 163 */ array(58, 63, ),
+        /* 164 */ array(17, 29, ),
+        /* 165 */ array(17, 29, ),
+        /* 166 */ array(17, 29, ),
+        /* 167 */ array(17, 29, ),
+        /* 168 */ array(17, 29, ),
+        /* 169 */ array(17, 29, ),
+        /* 170 */ array(17, 29, ),
+        /* 171 */ array(17, 29, ),
+        /* 172 */ array(17, 29, ),
+        /* 173 */ array(58, 63, ),
+        /* 174 */ array(17, 29, ),
+        /* 175 */ array(17, 29, ),
+        /* 176 */ array(17, 29, ),
+        /* 177 */ array(17, 29, ),
+        /* 178 */ array(17, 29, ),
+        /* 179 */ array(1, 17, ),
+        /* 180 */ array(17, 29, ),
+        /* 181 */ array(58, 63, ),
+        /* 182 */ array(17, 29, ),
+        /* 183 */ array(17, 29, ),
+        /* 184 */ array(1, 17, ),
+        /* 185 */ array(58, 63, ),
+        /* 186 */ array(17, 29, ),
+        /* 187 */ array(17, 29, ),
+        /* 188 */ array(1, 17, ),
+        /* 189 */ array(29, ),
+        /* 190 */ array(1, ),
+        /* 191 */ array(1, ),
+        /* 192 */ array(2, ),
+        /* 193 */ array(2, ),
+        /* 194 */ array(37, ),
+        /* 195 */ array(29, ),
+        /* 196 */ array(21, ),
+        /* 197 */ array(14, ),
+        /* 198 */ array(21, ),
+        /* 199 */ array(21, ),
+        /* 200 */ array(),
+        /* 201 */ array(),
+        /* 202 */ array(),
+        /* 203 */ array(),
+        /* 204 */ array(),
+        /* 205 */ array(17, 24, 26, 27, 29, 30, 36, 37, 38, 53, 60, 64, 78, ),
+        /* 206 */ array(17, 20, 29, 37, 60, ),
+        /* 207 */ array(16, 18, 19, 35, ),
+        /* 208 */ array(37, 58, 60, 64, ),
+        /* 209 */ array(17, 29, 37, 60, ),
+        /* 210 */ array(31, 37, 60, ),
+        /* 211 */ array(36, 38, ),
+        /* 212 */ array(24, 36, ),
+        /* 213 */ array(2, 20, ),
+        /* 214 */ array(25, 78, ),
+        /* 215 */ array(17, 25, ),
+        /* 216 */ array(36, 38, ),
+        /* 217 */ array(36, 38, ),
+        /* 218 */ array(19, 61, ),
+        /* 219 */ array(36, 64, ),
+        /* 220 */ array(37, 60, ),
+        /* 221 */ array(37, 60, ),
+        /* 222 */ array(20, 58, ),
+        /* 223 */ array(37, ),
+        /* 224 */ array(18, ),
+        /* 225 */ array(19, ),
+        /* 226 */ array(2, ),
+        /* 227 */ array(62, ),
+        /* 228 */ array(18, ),
+        /* 229 */ array(26, ),
+        /* 230 */ array(19, ),
+        /* 231 */ array(18, ),
+        /* 232 */ array(19, ),
+        /* 233 */ array(35, ),
+        /* 234 */ array(37, ),
+        /* 235 */ array(38, ),
+        /* 236 */ array(25, ),
+        /* 237 */ array(54, ),
+        /* 238 */ array(2, ),
+        /* 239 */ array(19, ),
+        /* 240 */ array(19, ),
+        /* 241 */ array(19, ),
+        /* 242 */ array(64, ),
+        /* 243 */ array(19, ),
+        /* 244 */ array(19, ),
+        /* 245 */ array(19, ),
+        /* 246 */ array(58, ),
+        /* 247 */ array(19, ),
+        /* 248 */ array(62, ),
+        /* 249 */ array(35, ),
+        /* 250 */ array(18, ),
+        /* 251 */ array(20, ),
+        /* 252 */ array(18, ),
+        /* 253 */ array(),
+        /* 254 */ array(),
+        /* 255 */ array(),
+        /* 256 */ array(),
+        /* 257 */ array(),
+        /* 258 */ array(),
+        /* 259 */ array(),
+        /* 260 */ array(),
+        /* 261 */ array(),
+        /* 262 */ array(),
+        /* 263 */ array(),
+        /* 264 */ array(),
+        /* 265 */ array(),
+        /* 266 */ array(),
+        /* 267 */ array(),
+        /* 268 */ array(),
+        /* 269 */ array(),
+        /* 270 */ array(),
+        /* 271 */ array(),
+        /* 272 */ array(),
+        /* 273 */ array(),
+        /* 274 */ array(),
+        /* 275 */ array(),
+        /* 276 */ array(),
+        /* 277 */ array(),
+        /* 278 */ array(),
+        /* 279 */ array(),
+        /* 280 */ array(),
+        /* 281 */ array(),
+        /* 282 */ array(),
+        /* 283 */ array(),
+        /* 284 */ array(),
+        /* 285 */ array(),
+        /* 286 */ array(),
+        /* 287 */ array(),
+        /* 288 */ array(),
+        /* 289 */ array(),
+        /* 290 */ array(),
+        /* 291 */ array(),
+        /* 292 */ array(),
+        /* 293 */ array(),
+        /* 294 */ array(),
+        /* 295 */ array(),
+        /* 296 */ array(),
+        /* 297 */ array(),
+        /* 298 */ array(),
+        /* 299 */ array(),
+        /* 300 */ array(),
+        /* 301 */ array(),
+        /* 302 */ array(),
+        /* 303 */ array(),
+        /* 304 */ array(),
+        /* 305 */ array(),
+        /* 306 */ array(),
+        /* 307 */ array(),
+        /* 308 */ array(),
+        /* 309 */ array(),
+        /* 310 */ array(),
+        /* 311 */ array(),
+        /* 312 */ array(),
+        /* 313 */ array(),
+        /* 314 */ array(),
+        /* 315 */ array(),
+        /* 316 */ array(),
+        /* 317 */ array(),
+        /* 318 */ array(),
+        /* 319 */ array(),
+        /* 320 */ array(),
+        /* 321 */ array(),
+        /* 322 */ array(),
+        /* 323 */ array(),
+        /* 324 */ array(),
+        /* 325 */ array(),
+        /* 326 */ array(),
+        /* 327 */ array(),
+        /* 328 */ array(),
+        /* 329 */ array(),
+        /* 330 */ array(),
+        /* 331 */ array(),
+        /* 332 */ array(),
+        /* 333 */ array(),
+        /* 334 */ array(),
+        /* 335 */ array(),
+        /* 336 */ array(),
+        /* 337 */ array(),
+        /* 338 */ array(),
+        /* 339 */ array(),
+        /* 340 */ array(),
+        /* 341 */ array(),
+        /* 342 */ array(),
+        /* 343 */ array(),
+        /* 344 */ array(),
+        /* 345 */ array(),
+        /* 346 */ array(),
+        /* 347 */ array(),
+        /* 348 */ array(),
+        /* 349 */ array(),
+        /* 350 */ array(),
+        /* 351 */ array(),
+        /* 352 */ array(),
+        /* 353 */ array(),
+        /* 354 */ array(),
+        /* 355 */ array(),
+        /* 356 */ array(),
+        /* 357 */ array(),
+        /* 358 */ array(),
+        /* 359 */ array(),
+        /* 360 */ array(),
+        /* 361 */ array(),
+        /* 362 */ array(),
+        /* 363 */ array(),
+        /* 364 */ array(),
+        /* 365 */ array(),
+        /* 366 */ array(),
+        /* 367 */ array(),
+        /* 368 */ array(),
+        /* 369 */ array(),
+        /* 370 */ array(),
+        /* 371 */ array(),
+        /* 372 */ array(),
+        /* 373 */ array(),
+        /* 374 */ array(),
+        /* 375 */ array(),
+        /* 376 */ array(),
+        /* 377 */ array(),
+        /* 378 */ array(),
+        /* 379 */ array(),
+        /* 380 */ array(),
+        /* 381 */ array(),
+        /* 382 */ array(),
+        /* 383 */ array(),
+        /* 384 */ array(),
+        /* 385 */ array(),
+        /* 386 */ array(),
+        /* 387 */ array(),
+);
+    static public $yy_default = array(
+ /*     0 */   391,  573,  544,  590,  544,  590,  590,  544,  590,  590,
+ /*    10 */   590,  590,  590,  590,  590,  590,  590,  590,  590,  590,
+ /*    20 */   590,  590,  590,  590,  590,  590,  590,  590,  590,  590,
+ /*    30 */   590,  590,  590,  590,  590,  590,  590,  590,  590,  590,
+ /*    40 */   590,  590,  590,  590,  590,  590,  590,  590,  590,  590,
+ /*    50 */   590,  590,  590,  590,  590,  590,  452,  452,  452,  452,
+ /*    60 */   590,  590,  590,  457,  590,  590,  590,  590,  590,  590,
+ /*    70 */   590,  542,  454,  481,  482,  485,  486,  478,  543,  476,
+ /*    80 */   463,  575,  576,  473,  459,  457,  477,  434,  462,  574,
+ /*    90 */   490,  489,  501,  465,  452,  388,  590,  452,  452,  509,
+ /*   100 */   472,  590,  452,  590,  556,  452,  452,  590,  452,  590,
+ /*   110 */   590,  465,  590,  465,  517,  465,  517,  510,  517,  510,
+ /*   120 */   465,  590,  465,  590,  590,  517,  590,  590,  590,  510,
+ /*   130 */   590,  590,  465,  590,  590,  590,  590,  590,  590,  590,
+ /*   140 */   590,  590,  590,  590,  590,  493,  553,  475,  492,  469,
+ /*   150 */   488,  468,  510,  452,  452,  470,  494,  551,  590,  518,
+ /*   160 */   590,  534,  517,  537,  590,  590,  590,  590,  590,  590,
+ /*   170 */   590,  590,  590,  535,  590,  590,  590,  590,  590,  590,
+ /*   180 */   590,  536,  590,  590,  590,  515,  590,  590,  590,  589,
+ /*   190 */   472,  509,  545,  546,  517,  589,  531,  407,  557,  554,
+ /*   200 */   550,  550,  517,  550,  517,  467,  501,  590,  501,  501,
+ /*   210 */   501,  590,  590,  529,  491,  491,  590,  590,  590,  590,
+ /*   220 */   501,  487,  497,  555,  590,  590,  529,  590,  590,  460,
+ /*   230 */   590,  590,  590,  590,  529,  590,  491,  503,  529,  590,
+ /*   240 */   590,  590,  590,  590,  590,  590,  497,  590,  590,  499,
+ /*   250 */   590,  590,  590,  437,  417,  389,  571,  431,  432,  441,
+ /*   260 */   572,  540,  435,  588,  461,  539,  525,  523,  503,  526,
+ /*   270 */   524,  514,  513,  530,  436,  570,  464,  538,  522,  442,
+ /*   280 */   552,  541,  567,  529,  528,  443,  444,  549,  440,  439,
+ /*   290 */   430,  429,  451,  433,  438,  445,  446,  498,  496,  500,
+ /*   300 */   506,  466,  495,  449,  447,  547,  548,  448,  450,  416,
+ /*   310 */   398,  397,  399,  400,  401,  396,  395,  390,  392,  393,
+ /*   320 */   394,  402,  403,  412,  411,  413,  414,  415,  410,  409,
+ /*   330 */   404,  405,  406,  408,  467,  511,  422,  421,  423,  532,
+ /*   340 */   424,  420,  585,  512,  508,  533,  418,  419,  425,  426,
+ /*   350 */   581,  582,  583,  586,  587,  579,  578,  428,  427,  584,
+ /*   360 */   577,  471,  569,  504,  474,  505,  507,  479,  502,  521,
+ /*   370 */   516,  519,  527,  520,  480,  483,  564,  563,  565,  566,
+ /*   380 */   568,  562,  561,  484,  558,  559,  560,  580,
+);
+    const YYNOCODE = 123;
+    const YYSTACKDEPTH = 100;
+    const YYNSTATE = 388;
+    const YYNRULE = 202;
+    const YYERRORSYMBOL = 80;
+    const YYERRSYMDT = 'yy0';
+    const YYFALLBACK = 0;
+    static public $yyFallback = array(
+    );
+    static function Trace($TraceFILE, $zTracePrompt)
+    {
+        if (!$TraceFILE) {
+            $zTracePrompt = 0;
+        } elseif (!$zTracePrompt) {
+            $TraceFILE = 0;
+        }
+        self::$yyTraceFILE = $TraceFILE;
+        self::$yyTracePrompt = $zTracePrompt;
+    }
+
+    static function PrintTrace()
+    {
+        self::$yyTraceFILE = fopen('php://output', 'w');
+        self::$yyTracePrompt = '<br>';
+    }
+
+    static public $yyTraceFILE;
+    static public $yyTracePrompt;
+    public $yyidx;                    /* Index of top element in stack */
+    public $yyerrcnt;                 /* Shifts left before out of the error */
+    public $yystack = array();  /* The parser's stack */
+
+    public $yyTokenName = array(
+  '$',             'VERT',          'COLON',         'COMMENT',
+  'PHPSTARTTAG',   'PHPENDTAG',     'ASPSTARTTAG',   'ASPENDTAG',
+  'FAKEPHPSTARTTAG',  'XMLTAG',        'TEXT',          'STRIPON',
+  'STRIPOFF',      'LITERALSTART',  'LITERALEND',    'LITERAL',
+  'LDEL',          'RDEL',          'DOLLAR',        'ID',
+  'EQUAL',         'PTR',           'LDELIF',        'LDELFOR',
+  'SEMICOLON',     'INCDEC',        'TO',            'STEP',
+  'LDELFOREACH',   'SPACE',         'AS',            'APTR',
+  'LDELSETFILTER',  'SMARTYBLOCKCHILD',  'LDELSLASH',     'INTEGER',
+  'COMMA',         'OPENP',         'CLOSEP',        'MATH',
+  'UNIMATH',       'ANDSYM',        'ISIN',          'ISDIVBY',
+  'ISNOTDIVBY',    'ISEVEN',        'ISNOTEVEN',     'ISEVENBY',
+  'ISNOTEVENBY',   'ISODD',         'ISNOTODD',      'ISODDBY',
+  'ISNOTODDBY',    'INSTANCEOF',    'QMARK',         'NOT',
+  'TYPECAST',      'HEX',           'DOT',           'SINGLEQUOTESTRING',
+  'DOUBLECOLON',   'AT',            'HATCH',         'OPENB',
+  'CLOSEB',        'EQUALS',        'NOTEQUALS',     'GREATERTHAN',
+  'LESSTHAN',      'GREATEREQUAL',  'LESSEQUAL',     'IDENTITY',
+  'NONEIDENTITY',  'MOD',           'LAND',          'LOR',
+  'LXOR',          'QUOTE',         'BACKTICK',      'DOLLARID',
+  'error',         'start',         'template',      'template_element',
+  'smartytag',     'literal',       'literal_elements',  'literal_element',
+  'value',         'modifierlist',  'attributes',    'expr',
+  'varindexed',    'statement',     'statements',    'optspace',
+  'varvar',        'foraction',     'modparameters',  'attribute',
+  'ternary',       'array',         'ifcond',        'lop',
+  'variable',      'function',      'doublequoted_with_quotes',  'static_class_access',
+  'object',        'arrayindex',    'indexdef',      'varvarele',
+  'objectchain',   'objectelement',  'method',        'params',
+  'modifier',      'modparameter',  'arrayelements',  'arrayelement',
+  'doublequoted',  'doublequotedcontent',
+    );
+
+    static public $yyRuleName = array(
+ /*   0 */ "start ::= template",
+ /*   1 */ "template ::= template_element",
+ /*   2 */ "template ::= template template_element",
+ /*   3 */ "template ::=",
+ /*   4 */ "template_element ::= smartytag",
+ /*   5 */ "template_element ::= COMMENT",
+ /*   6 */ "template_element ::= literal",
+ /*   7 */ "template_element ::= PHPSTARTTAG",
+ /*   8 */ "template_element ::= PHPENDTAG",
+ /*   9 */ "template_element ::= ASPSTARTTAG",
+ /*  10 */ "template_element ::= ASPENDTAG",
+ /*  11 */ "template_element ::= FAKEPHPSTARTTAG",
+ /*  12 */ "template_element ::= XMLTAG",
+ /*  13 */ "template_element ::= TEXT",
+ /*  14 */ "template_element ::= STRIPON",
+ /*  15 */ "template_element ::= STRIPOFF",
+ /*  16 */ "literal ::= LITERALSTART LITERALEND",
+ /*  17 */ "literal ::= LITERALSTART literal_elements LITERALEND",
+ /*  18 */ "literal_elements ::= literal_elements literal_element",
+ /*  19 */ "literal_elements ::=",
+ /*  20 */ "literal_element ::= literal",
+ /*  21 */ "literal_element ::= LITERAL",
+ /*  22 */ "literal_element ::= PHPSTARTTAG",
+ /*  23 */ "literal_element ::= FAKEPHPSTARTTAG",
+ /*  24 */ "literal_element ::= PHPENDTAG",
+ /*  25 */ "literal_element ::= ASPSTARTTAG",
+ /*  26 */ "literal_element ::= ASPENDTAG",
+ /*  27 */ "smartytag ::= LDEL value RDEL",
+ /*  28 */ "smartytag ::= LDEL value modifierlist attributes RDEL",
+ /*  29 */ "smartytag ::= LDEL value attributes RDEL",
+ /*  30 */ "smartytag ::= LDEL expr modifierlist attributes RDEL",
+ /*  31 */ "smartytag ::= LDEL expr attributes RDEL",
+ /*  32 */ "smartytag ::= LDEL DOLLAR ID EQUAL value RDEL",
+ /*  33 */ "smartytag ::= LDEL DOLLAR ID EQUAL expr RDEL",
+ /*  34 */ "smartytag ::= LDEL DOLLAR ID EQUAL expr attributes RDEL",
+ /*  35 */ "smartytag ::= LDEL varindexed EQUAL expr attributes RDEL",
+ /*  36 */ "smartytag ::= LDEL ID attributes RDEL",
+ /*  37 */ "smartytag ::= LDEL ID RDEL",
+ /*  38 */ "smartytag ::= LDEL ID PTR ID attributes RDEL",
+ /*  39 */ "smartytag ::= LDEL ID modifierlist attributes RDEL",
+ /*  40 */ "smartytag ::= LDEL ID PTR ID modifierlist attributes RDEL",
+ /*  41 */ "smartytag ::= LDELIF expr RDEL",
+ /*  42 */ "smartytag ::= LDELIF expr attributes RDEL",
+ /*  43 */ "smartytag ::= LDELIF statement RDEL",
+ /*  44 */ "smartytag ::= LDELIF statement attributes RDEL",
+ /*  45 */ "smartytag ::= LDELFOR statements SEMICOLON optspace expr SEMICOLON optspace DOLLAR varvar foraction attributes RDEL",
+ /*  46 */ "foraction ::= EQUAL expr",
+ /*  47 */ "foraction ::= INCDEC",
+ /*  48 */ "smartytag ::= LDELFOR statement TO expr attributes RDEL",
+ /*  49 */ "smartytag ::= LDELFOR statement TO expr STEP expr attributes RDEL",
+ /*  50 */ "smartytag ::= LDELFOREACH attributes RDEL",
+ /*  51 */ "smartytag ::= LDELFOREACH SPACE value AS DOLLAR varvar attributes RDEL",
+ /*  52 */ "smartytag ::= LDELFOREACH SPACE value AS DOLLAR varvar APTR DOLLAR varvar attributes RDEL",
+ /*  53 */ "smartytag ::= LDELFOREACH SPACE expr AS DOLLAR varvar attributes RDEL",
+ /*  54 */ "smartytag ::= LDELFOREACH SPACE expr AS DOLLAR varvar APTR DOLLAR varvar attributes RDEL",
+ /*  55 */ "smartytag ::= LDELSETFILTER ID modparameters RDEL",
+ /*  56 */ "smartytag ::= LDELSETFILTER ID modparameters modifierlist RDEL",
+ /*  57 */ "smartytag ::= SMARTYBLOCKCHILD",
+ /*  58 */ "smartytag ::= LDELSLASH ID RDEL",
+ /*  59 */ "smartytag ::= LDELSLASH ID modifierlist RDEL",
+ /*  60 */ "smartytag ::= LDELSLASH ID PTR ID RDEL",
+ /*  61 */ "smartytag ::= LDELSLASH ID PTR ID modifierlist RDEL",
+ /*  62 */ "attributes ::= attributes attribute",
+ /*  63 */ "attributes ::= attribute",
+ /*  64 */ "attributes ::=",
+ /*  65 */ "attribute ::= SPACE ID EQUAL ID",
+ /*  66 */ "attribute ::= SPACE ID EQUAL expr",
+ /*  67 */ "attribute ::= SPACE ID EQUAL value",
+ /*  68 */ "attribute ::= SPACE ID",
+ /*  69 */ "attribute ::= SPACE expr",
+ /*  70 */ "attribute ::= SPACE value",
+ /*  71 */ "attribute ::= SPACE INTEGER EQUAL expr",
+ /*  72 */ "statements ::= statement",
+ /*  73 */ "statements ::= statements COMMA statement",
+ /*  74 */ "statement ::= DOLLAR varvar EQUAL expr",
+ /*  75 */ "statement ::= varindexed EQUAL expr",
+ /*  76 */ "statement ::= OPENP statement CLOSEP",
+ /*  77 */ "expr ::= value",
+ /*  78 */ "expr ::= ternary",
+ /*  79 */ "expr ::= DOLLAR ID COLON ID",
+ /*  80 */ "expr ::= expr MATH value",
+ /*  81 */ "expr ::= expr UNIMATH value",
+ /*  82 */ "expr ::= expr ANDSYM value",
+ /*  83 */ "expr ::= array",
+ /*  84 */ "expr ::= expr modifierlist",
+ /*  85 */ "expr ::= expr ifcond expr",
+ /*  86 */ "expr ::= expr ISIN array",
+ /*  87 */ "expr ::= expr ISIN value",
+ /*  88 */ "expr ::= expr lop expr",
+ /*  89 */ "expr ::= expr ISDIVBY expr",
+ /*  90 */ "expr ::= expr ISNOTDIVBY expr",
+ /*  91 */ "expr ::= expr ISEVEN",
+ /*  92 */ "expr ::= expr ISNOTEVEN",
+ /*  93 */ "expr ::= expr ISEVENBY expr",
+ /*  94 */ "expr ::= expr ISNOTEVENBY expr",
+ /*  95 */ "expr ::= expr ISODD",
+ /*  96 */ "expr ::= expr ISNOTODD",
+ /*  97 */ "expr ::= expr ISODDBY expr",
+ /*  98 */ "expr ::= expr ISNOTODDBY expr",
+ /*  99 */ "expr ::= value INSTANCEOF ID",
+ /* 100 */ "expr ::= value INSTANCEOF value",
+ /* 101 */ "ternary ::= OPENP expr CLOSEP QMARK DOLLAR ID COLON expr",
+ /* 102 */ "ternary ::= OPENP expr CLOSEP QMARK expr COLON expr",
+ /* 103 */ "value ::= variable",
+ /* 104 */ "value ::= UNIMATH value",
+ /* 105 */ "value ::= NOT value",
+ /* 106 */ "value ::= TYPECAST value",
+ /* 107 */ "value ::= variable INCDEC",
+ /* 108 */ "value ::= HEX",
+ /* 109 */ "value ::= INTEGER",
+ /* 110 */ "value ::= INTEGER DOT INTEGER",
+ /* 111 */ "value ::= INTEGER DOT",
+ /* 112 */ "value ::= DOT INTEGER",
+ /* 113 */ "value ::= ID",
+ /* 114 */ "value ::= function",
+ /* 115 */ "value ::= OPENP expr CLOSEP",
+ /* 116 */ "value ::= SINGLEQUOTESTRING",
+ /* 117 */ "value ::= doublequoted_with_quotes",
+ /* 118 */ "value ::= ID DOUBLECOLON static_class_access",
+ /* 119 */ "value ::= varindexed DOUBLECOLON static_class_access",
+ /* 120 */ "value ::= smartytag",
+ /* 121 */ "value ::= value modifierlist",
+ /* 122 */ "variable ::= varindexed",
+ /* 123 */ "variable ::= DOLLAR varvar AT ID",
+ /* 124 */ "variable ::= object",
+ /* 125 */ "variable ::= HATCH ID HATCH",
+ /* 126 */ "variable ::= HATCH variable HATCH",
+ /* 127 */ "varindexed ::= DOLLAR varvar arrayindex",
+ /* 128 */ "arrayindex ::= arrayindex indexdef",
+ /* 129 */ "arrayindex ::=",
+ /* 130 */ "indexdef ::= DOT DOLLAR varvar",
+ /* 131 */ "indexdef ::= DOT DOLLAR varvar AT ID",
+ /* 132 */ "indexdef ::= DOT ID",
+ /* 133 */ "indexdef ::= DOT INTEGER",
+ /* 134 */ "indexdef ::= DOT LDEL expr RDEL",
+ /* 135 */ "indexdef ::= OPENB ID CLOSEB",
+ /* 136 */ "indexdef ::= OPENB ID DOT ID CLOSEB",
+ /* 137 */ "indexdef ::= OPENB expr CLOSEB",
+ /* 138 */ "indexdef ::= OPENB CLOSEB",
+ /* 139 */ "varvar ::= varvarele",
+ /* 140 */ "varvar ::= varvar varvarele",
+ /* 141 */ "varvarele ::= ID",
+ /* 142 */ "varvarele ::= LDEL expr RDEL",
+ /* 143 */ "object ::= varindexed objectchain",
+ /* 144 */ "objectchain ::= objectelement",
+ /* 145 */ "objectchain ::= objectchain objectelement",
+ /* 146 */ "objectelement ::= PTR ID arrayindex",
+ /* 147 */ "objectelement ::= PTR DOLLAR varvar arrayindex",
+ /* 148 */ "objectelement ::= PTR LDEL expr RDEL arrayindex",
+ /* 149 */ "objectelement ::= PTR ID LDEL expr RDEL arrayindex",
+ /* 150 */ "objectelement ::= PTR method",
+ /* 151 */ "function ::= ID OPENP params CLOSEP",
+ /* 152 */ "method ::= ID OPENP params CLOSEP",
+ /* 153 */ "method ::= DOLLAR ID OPENP params CLOSEP",
+ /* 154 */ "params ::= params COMMA expr",
+ /* 155 */ "params ::= expr",
+ /* 156 */ "params ::=",
+ /* 157 */ "modifierlist ::= modifierlist modifier modparameters",
+ /* 158 */ "modifierlist ::= modifier modparameters",
+ /* 159 */ "modifier ::= VERT AT ID",
+ /* 160 */ "modifier ::= VERT ID",
+ /* 161 */ "modparameters ::= modparameters modparameter",
+ /* 162 */ "modparameters ::=",
+ /* 163 */ "modparameter ::= COLON value",
+ /* 164 */ "modparameter ::= COLON array",
+ /* 165 */ "static_class_access ::= method",
+ /* 166 */ "static_class_access ::= method objectchain",
+ /* 167 */ "static_class_access ::= ID",
+ /* 168 */ "static_class_access ::= DOLLAR ID arrayindex",
+ /* 169 */ "static_class_access ::= DOLLAR ID arrayindex objectchain",
+ /* 170 */ "ifcond ::= EQUALS",
+ /* 171 */ "ifcond ::= NOTEQUALS",
+ /* 172 */ "ifcond ::= GREATERTHAN",
+ /* 173 */ "ifcond ::= LESSTHAN",
+ /* 174 */ "ifcond ::= GREATEREQUAL",
+ /* 175 */ "ifcond ::= LESSEQUAL",
+ /* 176 */ "ifcond ::= IDENTITY",
+ /* 177 */ "ifcond ::= NONEIDENTITY",
+ /* 178 */ "ifcond ::= MOD",
+ /* 179 */ "lop ::= LAND",
+ /* 180 */ "lop ::= LOR",
+ /* 181 */ "lop ::= LXOR",
+ /* 182 */ "array ::= OPENB arrayelements CLOSEB",
+ /* 183 */ "arrayelements ::= arrayelement",
+ /* 184 */ "arrayelements ::= arrayelements COMMA arrayelement",
+ /* 185 */ "arrayelements ::=",
+ /* 186 */ "arrayelement ::= value APTR expr",
+ /* 187 */ "arrayelement ::= ID APTR expr",
+ /* 188 */ "arrayelement ::= expr",
+ /* 189 */ "doublequoted_with_quotes ::= QUOTE QUOTE",
+ /* 190 */ "doublequoted_with_quotes ::= QUOTE doublequoted QUOTE",
+ /* 191 */ "doublequoted ::= doublequoted doublequotedcontent",
+ /* 192 */ "doublequoted ::= doublequotedcontent",
+ /* 193 */ "doublequotedcontent ::= BACKTICK variable BACKTICK",
+ /* 194 */ "doublequotedcontent ::= BACKTICK expr BACKTICK",
+ /* 195 */ "doublequotedcontent ::= DOLLARID",
+ /* 196 */ "doublequotedcontent ::= LDEL variable RDEL",
+ /* 197 */ "doublequotedcontent ::= LDEL expr RDEL",
+ /* 198 */ "doublequotedcontent ::= smartytag",
+ /* 199 */ "doublequotedcontent ::= TEXT",
+ /* 200 */ "optspace ::= SPACE",
+ /* 201 */ "optspace ::=",
+    );
+
+    function tokenName($tokenType)
+    {
+        if ($tokenType === 0) {
+            return 'End of Input';
+        }
+        if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) {
+            return $this->yyTokenName[$tokenType];
+        } else {
+            return "Unknown";
+        }
+    }
+
+    static function yy_destructor($yymajor, $yypminor)
+    {
+        switch ($yymajor) {
+            default:  break;   /* If no destructor action specified: do nothing */
+        }
+    }
+
+    function yy_pop_parser_stack()
+    {
+        if (!count($this->yystack)) {
+            return;
+        }
+        $yytos = array_pop($this->yystack);
+        if (self::$yyTraceFILE && $this->yyidx >= 0) {
+            fwrite(self::$yyTraceFILE,
+                self::$yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] .
+                    "\n");
+        }
+        $yymajor = $yytos->major;
+        self::yy_destructor($yymajor, $yytos->minor);
+        $this->yyidx--;
+        return $yymajor;
+    }
+
+    function __destruct()
+    {
+        while ($this->yystack !== Array()) {
+            $this->yy_pop_parser_stack();
+        }
+        if (is_resource(self::$yyTraceFILE)) {
+            fclose(self::$yyTraceFILE);
+        }
+    }
+
+    function yy_get_expected_tokens($token)
+    {
+        $state = $this->yystack[$this->yyidx]->stateno;
+        $expected = self::$yyExpectedTokens[$state];
+        if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+            return $expected;
+        }
+        $stack = $this->yystack;
+        $yyidx = $this->yyidx;
+        do {
+            $yyact = $this->yy_find_shift_action($token);
+            if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+                // reduce action
+                $done = 0;
+                do {
+                    if ($done++ == 100) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // too much recursion prevents proper detection
+                        // so give up
+                        return array_unique($expected);
+                    }
+                    $yyruleno = $yyact - self::YYNSTATE;
+                    $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+                    $nextstate = $this->yy_find_reduce_action(
+                        $this->yystack[$this->yyidx]->stateno,
+                        self::$yyRuleInfo[$yyruleno]['lhs']);
+                    if (isset(self::$yyExpectedTokens[$nextstate])) {
+		        $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]);
+                            if (in_array($token,
+                                  self::$yyExpectedTokens[$nextstate], true)) {
+                            $this->yyidx = $yyidx;
+                            $this->yystack = $stack;
+                            return array_unique($expected);
+                        }
+                    }
+                    if ($nextstate < self::YYNSTATE) {
+                        // we need to shift a non-terminal
+                        $this->yyidx++;
+                        $x = new TP_yyStackEntry;
+                        $x->stateno = $nextstate;
+                        $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+                        $this->yystack[$this->yyidx] = $x;
+                        continue 2;
+                    } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // the last token was just ignored, we can't accept
+                        // by ignoring input, this is in essence ignoring a
+                        // syntax error!
+                        return array_unique($expected);
+                    } elseif ($nextstate === self::YY_NO_ACTION) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // input accepted, but not shifted (I guess)
+                        return $expected;
+                    } else {
+                        $yyact = $nextstate;
+                    }
+                } while (true);
+            }
+            break;
+        } while (true);
+	$this->yyidx = $yyidx;
+	$this->yystack = $stack;
+        return array_unique($expected);
+    }
+
+    function yy_is_expected_token($token)
+    {
+        if ($token === 0) {
+            return true; // 0 is not part of this
+        }
+        $state = $this->yystack[$this->yyidx]->stateno;
+        if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+            return true;
+        }
+        $stack = $this->yystack;
+        $yyidx = $this->yyidx;
+        do {
+            $yyact = $this->yy_find_shift_action($token);
+            if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+                // reduce action
+                $done = 0;
+                do {
+                    if ($done++ == 100) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // too much recursion prevents proper detection
+                        // so give up
+                        return true;
+                    }
+                    $yyruleno = $yyact - self::YYNSTATE;
+                    $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+                    $nextstate = $this->yy_find_reduce_action(
+                        $this->yystack[$this->yyidx]->stateno,
+                        self::$yyRuleInfo[$yyruleno]['lhs']);
+                    if (isset(self::$yyExpectedTokens[$nextstate]) &&
+                          in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        return true;
+                    }
+                    if ($nextstate < self::YYNSTATE) {
+                        // we need to shift a non-terminal
+                        $this->yyidx++;
+                        $x = new TP_yyStackEntry;
+                        $x->stateno = $nextstate;
+                        $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+                        $this->yystack[$this->yyidx] = $x;
+                        continue 2;
+                    } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        if (!$token) {
+                            // end of input: this is valid
+                            return true;
+                        }
+                        // the last token was just ignored, we can't accept
+                        // by ignoring input, this is in essence ignoring a
+                        // syntax error!
+                        return false;
+                    } elseif ($nextstate === self::YY_NO_ACTION) {
+                        $this->yyidx = $yyidx;
+                        $this->yystack = $stack;
+                        // input accepted, but not shifted (I guess)
+                        return true;
+                    } else {
+                        $yyact = $nextstate;
+                    }
+                } while (true);
+            }
+            break;
+        } while (true);
+        $this->yyidx = $yyidx;
+        $this->yystack = $stack;
+        return true;
+    }
+
+   function yy_find_shift_action($iLookAhead)
+    {
+        $stateno = $this->yystack[$this->yyidx]->stateno;
+
+        /* if ($this->yyidx < 0) return self::YY_NO_ACTION;  */
+        if (!isset(self::$yy_shift_ofst[$stateno])) {
+            // no shift actions
+            return self::$yy_default[$stateno];
+        }
+        $i = self::$yy_shift_ofst[$stateno];
+        if ($i === self::YY_SHIFT_USE_DFLT) {
+            return self::$yy_default[$stateno];
+        }
+        if ($iLookAhead == self::YYNOCODE) {
+            return self::YY_NO_ACTION;
+        }
+        $i += $iLookAhead;
+        if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+              self::$yy_lookahead[$i] != $iLookAhead) {
+            if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
+                   && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+                if (self::$yyTraceFILE) {
+                    fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
+                        $this->yyTokenName[$iLookAhead] . " => " .
+                        $this->yyTokenName[$iFallback] . "\n");
+                }
+                return $this->yy_find_shift_action($iFallback);
+            }
+            return self::$yy_default[$stateno];
+        } else {
+            return self::$yy_action[$i];
+        }
+    }
+
+    function yy_find_reduce_action($stateno, $iLookAhead)
+    {
+        /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+        if (!isset(self::$yy_reduce_ofst[$stateno])) {
+            return self::$yy_default[$stateno];
+        }
+        $i = self::$yy_reduce_ofst[$stateno];
+        if ($i == self::YY_REDUCE_USE_DFLT) {
+            return self::$yy_default[$stateno];
+        }
+        if ($iLookAhead == self::YYNOCODE) {
+            return self::YY_NO_ACTION;
+        }
+        $i += $iLookAhead;
+        if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+              self::$yy_lookahead[$i] != $iLookAhead) {
+            return self::$yy_default[$stateno];
+        } else {
+            return self::$yy_action[$i];
+        }
+    }
+
+    function yy_shift($yyNewState, $yyMajor, $yypMinor)
+    {
+        $this->yyidx++;
+        if ($this->yyidx >= self::YYSTACKDEPTH) {
+            $this->yyidx--;
+            if (self::$yyTraceFILE) {
+                fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
+            }
+            while ($this->yyidx >= 0) {
+                $this->yy_pop_parser_stack();
+            }
+#line 84 "smarty_internal_templateparser.y"
+
+    $this->internalError = true;
+    $this->compiler->trigger_template_error("Stack overflow in template parser");
+#line 1753 "smarty_internal_templateparser.php"
+            return;
+        }
+        $yytos = new TP_yyStackEntry;
+        $yytos->stateno = $yyNewState;
+        $yytos->major = $yyMajor;
+        $yytos->minor = $yypMinor;
+        array_push($this->yystack, $yytos);
+        if (self::$yyTraceFILE && $this->yyidx > 0) {
+            fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
+                $yyNewState);
+            fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
+            for($i = 1; $i <= $this->yyidx; $i++) {
+                fprintf(self::$yyTraceFILE, " %s",
+                    $this->yyTokenName[$this->yystack[$i]->major]);
+            }
+            fwrite(self::$yyTraceFILE,"\n");
+        }
+    }
+
+    static public $yyRuleInfo = array(
+  array( 'lhs' => 81, 'rhs' => 1 ),
+  array( 'lhs' => 82, 'rhs' => 1 ),
+  array( 'lhs' => 82, 'rhs' => 2 ),
+  array( 'lhs' => 82, 'rhs' => 0 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 83, 'rhs' => 1 ),
+  array( 'lhs' => 85, 'rhs' => 2 ),
+  array( 'lhs' => 85, 'rhs' => 3 ),
+  array( 'lhs' => 86, 'rhs' => 2 ),
+  array( 'lhs' => 86, 'rhs' => 0 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 87, 'rhs' => 1 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 5 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 5 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 84, 'rhs' => 7 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 84, 'rhs' => 5 ),
+  array( 'lhs' => 84, 'rhs' => 7 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 12 ),
+  array( 'lhs' => 97, 'rhs' => 2 ),
+  array( 'lhs' => 97, 'rhs' => 1 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 84, 'rhs' => 8 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 8 ),
+  array( 'lhs' => 84, 'rhs' => 11 ),
+  array( 'lhs' => 84, 'rhs' => 8 ),
+  array( 'lhs' => 84, 'rhs' => 11 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 5 ),
+  array( 'lhs' => 84, 'rhs' => 1 ),
+  array( 'lhs' => 84, 'rhs' => 3 ),
+  array( 'lhs' => 84, 'rhs' => 4 ),
+  array( 'lhs' => 84, 'rhs' => 5 ),
+  array( 'lhs' => 84, 'rhs' => 6 ),
+  array( 'lhs' => 90, 'rhs' => 2 ),
+  array( 'lhs' => 90, 'rhs' => 1 ),
+  array( 'lhs' => 90, 'rhs' => 0 ),
+  array( 'lhs' => 99, 'rhs' => 4 ),
+  array( 'lhs' => 99, 'rhs' => 4 ),
+  array( 'lhs' => 99, 'rhs' => 4 ),
+  array( 'lhs' => 99, 'rhs' => 2 ),
+  array( 'lhs' => 99, 'rhs' => 2 ),
+  array( 'lhs' => 99, 'rhs' => 2 ),
+  array( 'lhs' => 99, 'rhs' => 4 ),
+  array( 'lhs' => 94, 'rhs' => 1 ),
+  array( 'lhs' => 94, 'rhs' => 3 ),
+  array( 'lhs' => 93, 'rhs' => 4 ),
+  array( 'lhs' => 93, 'rhs' => 3 ),
+  array( 'lhs' => 93, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 1 ),
+  array( 'lhs' => 91, 'rhs' => 1 ),
+  array( 'lhs' => 91, 'rhs' => 4 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 1 ),
+  array( 'lhs' => 91, 'rhs' => 2 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 2 ),
+  array( 'lhs' => 91, 'rhs' => 2 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 2 ),
+  array( 'lhs' => 91, 'rhs' => 2 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 91, 'rhs' => 3 ),
+  array( 'lhs' => 100, 'rhs' => 8 ),
+  array( 'lhs' => 100, 'rhs' => 7 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 3 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 3 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 3 ),
+  array( 'lhs' => 88, 'rhs' => 3 ),
+  array( 'lhs' => 88, 'rhs' => 1 ),
+  array( 'lhs' => 88, 'rhs' => 2 ),
+  array( 'lhs' => 104, 'rhs' => 1 ),
+  array( 'lhs' => 104, 'rhs' => 4 ),
+  array( 'lhs' => 104, 'rhs' => 1 ),
+  array( 'lhs' => 104, 'rhs' => 3 ),
+  array( 'lhs' => 104, 'rhs' => 3 ),
+  array( 'lhs' => 92, 'rhs' => 3 ),
+  array( 'lhs' => 109, 'rhs' => 2 ),
+  array( 'lhs' => 109, 'rhs' => 0 ),
+  array( 'lhs' => 110, 'rhs' => 3 ),
+  array( 'lhs' => 110, 'rhs' => 5 ),
+  array( 'lhs' => 110, 'rhs' => 2 ),
+  array( 'lhs' => 110, 'rhs' => 2 ),
+  array( 'lhs' => 110, 'rhs' => 4 ),
+  array( 'lhs' => 110, 'rhs' => 3 ),
+  array( 'lhs' => 110, 'rhs' => 5 ),
+  array( 'lhs' => 110, 'rhs' => 3 ),
+  array( 'lhs' => 110, 'rhs' => 2 ),
+  array( 'lhs' => 96, 'rhs' => 1 ),
+  array( 'lhs' => 96, 'rhs' => 2 ),
+  array( 'lhs' => 111, 'rhs' => 1 ),
+  array( 'lhs' => 111, 'rhs' => 3 ),
+  array( 'lhs' => 108, 'rhs' => 2 ),
+  array( 'lhs' => 112, 'rhs' => 1 ),
+  array( 'lhs' => 112, 'rhs' => 2 ),
+  array( 'lhs' => 113, 'rhs' => 3 ),
+  array( 'lhs' => 113, 'rhs' => 4 ),
+  array( 'lhs' => 113, 'rhs' => 5 ),
+  array( 'lhs' => 113, 'rhs' => 6 ),
+  array( 'lhs' => 113, 'rhs' => 2 ),
+  array( 'lhs' => 105, 'rhs' => 4 ),
+  array( 'lhs' => 114, 'rhs' => 4 ),
+  array( 'lhs' => 114, 'rhs' => 5 ),
+  array( 'lhs' => 115, 'rhs' => 3 ),
+  array( 'lhs' => 115, 'rhs' => 1 ),
+  array( 'lhs' => 115, 'rhs' => 0 ),
+  array( 'lhs' => 89, 'rhs' => 3 ),
+  array( 'lhs' => 89, 'rhs' => 2 ),
+  array( 'lhs' => 116, 'rhs' => 3 ),
+  array( 'lhs' => 116, 'rhs' => 2 ),
+  array( 'lhs' => 98, 'rhs' => 2 ),
+  array( 'lhs' => 98, 'rhs' => 0 ),
+  array( 'lhs' => 117, 'rhs' => 2 ),
+  array( 'lhs' => 117, 'rhs' => 2 ),
+  array( 'lhs' => 107, 'rhs' => 1 ),
+  array( 'lhs' => 107, 'rhs' => 2 ),
+  array( 'lhs' => 107, 'rhs' => 1 ),
+  array( 'lhs' => 107, 'rhs' => 3 ),
+  array( 'lhs' => 107, 'rhs' => 4 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 102, 'rhs' => 1 ),
+  array( 'lhs' => 103, 'rhs' => 1 ),
+  array( 'lhs' => 103, 'rhs' => 1 ),
+  array( 'lhs' => 103, 'rhs' => 1 ),
+  array( 'lhs' => 101, 'rhs' => 3 ),
+  array( 'lhs' => 118, 'rhs' => 1 ),
+  array( 'lhs' => 118, 'rhs' => 3 ),
+  array( 'lhs' => 118, 'rhs' => 0 ),
+  array( 'lhs' => 119, 'rhs' => 3 ),
+  array( 'lhs' => 119, 'rhs' => 3 ),
+  array( 'lhs' => 119, 'rhs' => 1 ),
+  array( 'lhs' => 106, 'rhs' => 2 ),
+  array( 'lhs' => 106, 'rhs' => 3 ),
+  array( 'lhs' => 120, 'rhs' => 2 ),
+  array( 'lhs' => 120, 'rhs' => 1 ),
+  array( 'lhs' => 121, 'rhs' => 3 ),
+  array( 'lhs' => 121, 'rhs' => 3 ),
+  array( 'lhs' => 121, 'rhs' => 1 ),
+  array( 'lhs' => 121, 'rhs' => 3 ),
+  array( 'lhs' => 121, 'rhs' => 3 ),
+  array( 'lhs' => 121, 'rhs' => 1 ),
+  array( 'lhs' => 121, 'rhs' => 1 ),
+  array( 'lhs' => 95, 'rhs' => 1 ),
+  array( 'lhs' => 95, 'rhs' => 0 ),
+    );
+
+    static public $yyReduceMap = array(
+        0 => 0,
+        1 => 1,
+        2 => 1,
+        4 => 4,
+        5 => 5,
+        6 => 6,
+        7 => 7,
+        8 => 8,
+        9 => 9,
+        10 => 10,
+        11 => 11,
+        12 => 12,
+        13 => 13,
+        14 => 14,
+        15 => 15,
+        16 => 16,
+        19 => 16,
+        201 => 16,
+        17 => 17,
+        76 => 17,
+        18 => 18,
+        104 => 18,
+        106 => 18,
+        107 => 18,
+        128 => 18,
+        166 => 18,
+        20 => 20,
+        21 => 20,
+        47 => 20,
+        69 => 20,
+        70 => 20,
+        77 => 20,
+        78 => 20,
+        83 => 20,
+        103 => 20,
+        108 => 20,
+        109 => 20,
+        114 => 20,
+        116 => 20,
+        117 => 20,
+        124 => 20,
+        139 => 20,
+        165 => 20,
+        167 => 20,
+        183 => 20,
+        188 => 20,
+        200 => 20,
+        22 => 22,
+        23 => 22,
+        24 => 24,
+        25 => 25,
+        26 => 26,
+        27 => 27,
+        28 => 28,
+        29 => 29,
+        31 => 29,
+        30 => 30,
+        32 => 32,
+        33 => 32,
+        34 => 34,
+        35 => 35,
+        36 => 36,
+        37 => 37,
+        38 => 38,
+        39 => 39,
+        40 => 40,
+        41 => 41,
+        42 => 42,
+        44 => 42,
+        43 => 43,
+        45 => 45,
+        46 => 46,
+        48 => 48,
+        49 => 49,
+        50 => 50,
+        51 => 51,
+        52 => 52,
+        53 => 53,
+        54 => 54,
+        55 => 55,
+        56 => 56,
+        57 => 57,
+        58 => 58,
+        59 => 59,
+        60 => 60,
+        61 => 61,
+        62 => 62,
+        63 => 63,
+        72 => 63,
+        155 => 63,
+        159 => 63,
+        163 => 63,
+        164 => 63,
+        64 => 64,
+        156 => 64,
+        162 => 64,
+        65 => 65,
+        66 => 66,
+        67 => 66,
+        71 => 66,
+        68 => 68,
+        73 => 73,
+        74 => 74,
+        75 => 74,
+        79 => 79,
+        80 => 80,
+        81 => 80,
+        82 => 80,
+        84 => 84,
+        121 => 84,
+        85 => 85,
+        88 => 85,
+        99 => 85,
+        86 => 86,
+        87 => 87,
+        89 => 89,
+        90 => 90,
+        91 => 91,
+        96 => 91,
+        92 => 92,
+        95 => 92,
+        93 => 93,
+        98 => 93,
+        94 => 94,
+        97 => 94,
+        100 => 100,
+        101 => 101,
+        102 => 102,
+        105 => 105,
+        110 => 110,
+        111 => 111,
+        112 => 112,
+        113 => 113,
+        115 => 115,
+        118 => 118,
+        119 => 119,
+        120 => 120,
+        122 => 122,
+        123 => 123,
+        125 => 125,
+        126 => 126,
+        127 => 127,
+        129 => 129,
+        185 => 129,
+        130 => 130,
+        131 => 131,
+        132 => 132,
+        133 => 133,
+        134 => 134,
+        137 => 134,
+        135 => 135,
+        136 => 136,
+        138 => 138,
+        140 => 140,
+        141 => 141,
+        142 => 142,
+        143 => 143,
+        144 => 144,
+        145 => 145,
+        146 => 146,
+        147 => 147,
+        148 => 148,
+        149 => 149,
+        150 => 150,
+        151 => 151,
+        152 => 152,
+        153 => 153,
+        154 => 154,
+        157 => 157,
+        158 => 158,
+        160 => 160,
+        161 => 161,
+        168 => 168,
+        169 => 169,
+        170 => 170,
+        171 => 171,
+        172 => 172,
+        173 => 173,
+        174 => 174,
+        175 => 175,
+        176 => 176,
+        177 => 177,
+        178 => 178,
+        179 => 179,
+        180 => 180,
+        181 => 181,
+        182 => 182,
+        184 => 184,
+        186 => 186,
+        187 => 187,
+        189 => 189,
+        190 => 190,
+        191 => 191,
+        192 => 192,
+        193 => 193,
+        194 => 193,
+        196 => 193,
+        195 => 195,
+        197 => 197,
+        198 => 198,
+        199 => 199,
+    );
+#line 95 "smarty_internal_templateparser.y"
+    function yy_r0(){
+    $this->_retvalue = $this->root_buffer->to_smarty_php();
+    }
+#line 2185 "smarty_internal_templateparser.php"
+#line 103 "smarty_internal_templateparser.y"
+    function yy_r1(){
+    $this->current_buffer->append_subtree($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2190 "smarty_internal_templateparser.php"
+#line 119 "smarty_internal_templateparser.y"
+    function yy_r4(){
+    if ($this->compiler->has_code) {
+        $tmp =''; foreach ($this->compiler->prefix_code as $code) {$tmp.=$code;} $this->compiler->prefix_code=array();
+        $this->_retvalue = new _smarty_tag($this, $this->compiler->processNocacheCode($tmp.$this->yystack[$this->yyidx + 0]->minor,true));
+    } else {
+        $this->_retvalue = new _smarty_tag($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+    $this->compiler->has_variable_string = false;
+    $this->block_nesting_level = count($this->compiler->_tag_stack);
+    }
+#line 2202 "smarty_internal_templateparser.php"
+#line 131 "smarty_internal_templateparser.y"
+    function yy_r5(){
+    $this->_retvalue = new _smarty_tag($this, '');
+    }
+#line 2207 "smarty_internal_templateparser.php"
+#line 136 "smarty_internal_templateparser.y"
+    function yy_r6(){
+    $this->_retvalue = new _smarty_text($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2212 "smarty_internal_templateparser.php"
+#line 141 "smarty_internal_templateparser.y"
+    function yy_r7(){
+    if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+        $this->_retvalue = new _smarty_text($this, self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor));
+    } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+        $this->_retvalue = new _smarty_text($this, htmlspecialchars($this->yystack[$this->yyidx + 0]->minor, ENT_QUOTES));
+    } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+        if (!($this->smarty instanceof SmartyBC)) {
+            $this->compiler->trigger_template_error (self::Err3);
+        }
+        $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('<?php', true));
+    } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+        $this->_retvalue = new _smarty_text($this, '');
+    }
+    }
+#line 2228 "smarty_internal_templateparser.php"
+#line 157 "smarty_internal_templateparser.y"
+    function yy_r8(){
+    if ($this->is_xml) {
+        $this->compiler->tag_nocache = true;
+        $this->is_xml = false;
+        $save = $this->template->has_nocache_code;
+        $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode("<?php echo '?>';?>", $this->compiler, true));
+        $this->template->has_nocache_code = $save;
+    } elseif ($this->php_handling == Smarty::PHP_PASSTHRU) {
+        $this->_retvalue = new _smarty_text($this, '?<?php ?>>');
+    } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+        $this->_retvalue = new _smarty_text($this, htmlspecialchars('?>', ENT_QUOTES));
+    } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+        $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('?>', true));
+    } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+        $this->_retvalue = new _smarty_text($this, '');
+    }
+    }
+#line 2247 "smarty_internal_templateparser.php"
+#line 176 "smarty_internal_templateparser.y"
+    function yy_r9(){
+    if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+        $this->_retvalue = new _smarty_text($this, '<<?php ?>%');
+    } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+        $this->_retvalue = new _smarty_text($this, htmlspecialchars($this->yystack[$this->yyidx + 0]->minor, ENT_QUOTES));
+    } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+        if ($this->asp_tags) {
+            if (!($this->smarty instanceof SmartyBC)) {
+                $this->compiler->trigger_template_error (self::Err3);
+            }
+            $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('<%', true));
+        } else {
+            $this->_retvalue = new _smarty_text($this, '<<?php ?>%');
+        }
+    } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+        if ($this->asp_tags) {
+            $this->_retvalue = new _smarty_text($this, '');
+        } else {
+            $this->_retvalue = new _smarty_text($this, '<<?php ?>%');
+        }
+    }
+    }
+#line 2271 "smarty_internal_templateparser.php"
+#line 200 "smarty_internal_templateparser.y"
+    function yy_r10(){
+    if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+        $this->_retvalue = new _smarty_text($this, '%<?php ?>>');
+    } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+        $this->_retvalue = new _smarty_text($this, htmlspecialchars('%>', ENT_QUOTES));
+    } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+        if ($this->asp_tags) {
+            $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('%>', true));
+        } else {
+            $this->_retvalue = new _smarty_text($this, '%<?php ?>>');
+        }
+    } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+        if ($this->asp_tags) {
+            $this->_retvalue = new _smarty_text($this, '');
+        } else {
+            $this->_retvalue = new _smarty_text($this, '%<?php ?>>');
+        }
+    }
+    }
+#line 2292 "smarty_internal_templateparser.php"
+#line 220 "smarty_internal_templateparser.y"
+    function yy_r11(){
+    if ($this->strip) {
+        $this->_retvalue = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor)));
+    } else {
+        $this->_retvalue = new _smarty_text($this, self::escape_start_tag(ö));
+    }
+    }
+#line 2301 "smarty_internal_templateparser.php"
+#line 229 "smarty_internal_templateparser.y"
+    function yy_r12(){
+    $this->compiler->tag_nocache = true;
+    $this->is_xml = true;
+    $save = $this->template->has_nocache_code;
+    $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode("<?php echo '<?xml';?>", $this->compiler, true));
+    $this->template->has_nocache_code = $save;
+    }
+#line 2310 "smarty_internal_templateparser.php"
+#line 238 "smarty_internal_templateparser.y"
+    function yy_r13(){
+    if ($this->strip) {
+        $this->_retvalue = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $this->yystack[$this->yyidx + 0]->minor));
+    } else {
+        $this->_retvalue = new _smarty_text($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+    }
+#line 2319 "smarty_internal_templateparser.php"
+#line 247 "smarty_internal_templateparser.y"
+    function yy_r14(){
+    $this->strip = true;
+    $this->_retvalue = new _smarty_text($this, '');
+    }
+#line 2325 "smarty_internal_templateparser.php"
+#line 252 "smarty_internal_templateparser.y"
+    function yy_r15(){
+    $this->strip = false;
+    $this->_retvalue = new _smarty_text($this, '');
+    }
+#line 2331 "smarty_internal_templateparser.php"
+#line 258 "smarty_internal_templateparser.y"
+    function yy_r16(){
+    $this->_retvalue = '';
+    }
+#line 2336 "smarty_internal_templateparser.php"
+#line 262 "smarty_internal_templateparser.y"
+    function yy_r17(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+    }
+#line 2341 "smarty_internal_templateparser.php"
+#line 266 "smarty_internal_templateparser.y"
+    function yy_r18(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2346 "smarty_internal_templateparser.php"
+#line 274 "smarty_internal_templateparser.y"
+    function yy_r20(){
+    $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2351 "smarty_internal_templateparser.php"
+#line 282 "smarty_internal_templateparser.y"
+    function yy_r22(){
+    $this->_retvalue = self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2356 "smarty_internal_templateparser.php"
+#line 290 "smarty_internal_templateparser.y"
+    function yy_r24(){
+    $this->_retvalue = self::escape_end_tag($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2361 "smarty_internal_templateparser.php"
+#line 294 "smarty_internal_templateparser.y"
+    function yy_r25(){
+    $this->_retvalue = '<<?php ?>%';
+    }
+#line 2366 "smarty_internal_templateparser.php"
+#line 298 "smarty_internal_templateparser.y"
+    function yy_r26(){
+    $this->_retvalue = '%<?php ?>>';
+    }
+#line 2371 "smarty_internal_templateparser.php"
+#line 307 "smarty_internal_templateparser.y"
+    function yy_r27(){
+    $this->_retvalue = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2376 "smarty_internal_templateparser.php"
+#line 311 "smarty_internal_templateparser.y"
+    function yy_r28(){
+    $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -3]->minor, 'modifierlist'=>$this->yystack[$this->yyidx + -2]->minor));
+    }
+#line 2381 "smarty_internal_templateparser.php"
+#line 315 "smarty_internal_templateparser.y"
+    function yy_r29(){
+    $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -2]->minor));
+    }
+#line 2386 "smarty_internal_templateparser.php"
+#line 319 "smarty_internal_templateparser.y"
+    function yy_r30(){
+    $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -3]->minor,'modifierlist'=>$this->yystack[$this->yyidx + -2]->minor));
+    }
+#line 2391 "smarty_internal_templateparser.php"
+#line 332 "smarty_internal_templateparser.y"
+    function yy_r32(){
+    $this->_retvalue = $this->compiler->compileTag('assign',array(array('value'=>$this->yystack[$this->yyidx + -1]->minor),array('var'=>"'".$this->yystack[$this->yyidx + -3]->minor."'")));
+    }
+#line 2396 "smarty_internal_templateparser.php"
+#line 340 "smarty_internal_templateparser.y"
+    function yy_r34(){
+    $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + -2]->minor),array('var'=>"'".$this->yystack[$this->yyidx + -4]->minor."'")),$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2401 "smarty_internal_templateparser.php"
+#line 344 "smarty_internal_templateparser.y"
+    function yy_r35(){
+    $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + -2]->minor),array('var'=>$this->yystack[$this->yyidx + -4]->minor['var'])),$this->yystack[$this->yyidx + -1]->minor),array('smarty_internal_index'=>$this->yystack[$this->yyidx + -4]->minor['smarty_internal_index']));
+    }
+#line 2406 "smarty_internal_templateparser.php"
+#line 349 "smarty_internal_templateparser.y"
+    function yy_r36(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor,$this->yystack[$this->yyidx + -1]->minor);
+    }
+#line 2411 "smarty_internal_templateparser.php"
+#line 353 "smarty_internal_templateparser.y"
+    function yy_r37(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor,array());
+    }
+#line 2416 "smarty_internal_templateparser.php"
+#line 358 "smarty_internal_templateparser.y"
+    function yy_r38(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor,$this->yystack[$this->yyidx + -1]->minor,array('object_methode'=>$this->yystack[$this->yyidx + -2]->minor));
+    }
+#line 2421 "smarty_internal_templateparser.php"
+#line 363 "smarty_internal_templateparser.y"
+    function yy_r39(){
+    $this->_retvalue = '<?php ob_start();?>'.$this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor,$this->yystack[$this->yyidx + -1]->minor).'<?php echo ';
+    $this->_retvalue .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>$this->yystack[$this->yyidx + -2]->minor,'value'=>'ob_get_clean()')).'?>';
+    }
+#line 2427 "smarty_internal_templateparser.php"
+#line 369 "smarty_internal_templateparser.y"
+    function yy_r40(){
+    $this->_retvalue = '<?php ob_start();?>'.$this->compiler->compileTag($this->yystack[$this->yyidx + -5]->minor,$this->yystack[$this->yyidx + -1]->minor,array('object_methode'=>$this->yystack[$this->yyidx + -3]->minor)).'<?php echo ';
+    $this->_retvalue .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>$this->yystack[$this->yyidx + -2]->minor,'value'=>'ob_get_clean()')).'?>';
+    }
+#line 2433 "smarty_internal_templateparser.php"
+#line 375 "smarty_internal_templateparser.y"
+    function yy_r41(){
+    $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->lex->ldel_length));
+    $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2439 "smarty_internal_templateparser.php"
+#line 380 "smarty_internal_templateparser.y"
+    function yy_r42(){
+    $tag = trim(substr($this->yystack[$this->yyidx + -3]->minor,$this->lex->ldel_length));
+    $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,$this->yystack[$this->yyidx + -1]->minor,array('if condition'=>$this->yystack[$this->yyidx + -2]->minor));
+    }
+#line 2445 "smarty_internal_templateparser.php"
+#line 385 "smarty_internal_templateparser.y"
+    function yy_r43(){
+    $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->lex->ldel_length));
+    $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2451 "smarty_internal_templateparser.php"
+#line 396 "smarty_internal_templateparser.y"
+    function yy_r45(){
+    $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -10]->minor),array('ifexp'=>$this->yystack[$this->yyidx + -7]->minor),array('var'=>$this->yystack[$this->yyidx + -3]->minor),array('step'=>$this->yystack[$this->yyidx + -2]->minor))),1);
+    }
+#line 2456 "smarty_internal_templateparser.php"
+#line 400 "smarty_internal_templateparser.y"
+    function yy_r46(){
+    $this->_retvalue = '='.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2461 "smarty_internal_templateparser.php"
+#line 408 "smarty_internal_templateparser.y"
+    function yy_r48(){
+    $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -4]->minor),array('to'=>$this->yystack[$this->yyidx + -2]->minor))),0);
+    }
+#line 2466 "smarty_internal_templateparser.php"
+#line 412 "smarty_internal_templateparser.y"
+    function yy_r49(){
+    $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -6]->minor),array('to'=>$this->yystack[$this->yyidx + -4]->minor),array('step'=>$this->yystack[$this->yyidx + -2]->minor))),0);
+    }
+#line 2471 "smarty_internal_templateparser.php"
+#line 417 "smarty_internal_templateparser.y"
+    function yy_r50(){
+    $this->_retvalue = $this->compiler->compileTag('foreach',$this->yystack[$this->yyidx + -1]->minor);
+    }
+#line 2476 "smarty_internal_templateparser.php"
+#line 422 "smarty_internal_templateparser.y"
+    function yy_r51(){
+    $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor))));
+    }
+#line 2481 "smarty_internal_templateparser.php"
+#line 426 "smarty_internal_templateparser.y"
+    function yy_r52(){
+    $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -8]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor),array('key'=>$this->yystack[$this->yyidx + -5]->minor))));
+    }
+#line 2486 "smarty_internal_templateparser.php"
+#line 430 "smarty_internal_templateparser.y"
+    function yy_r53(){
+    $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor))));
+    }
+#line 2491 "smarty_internal_templateparser.php"
+#line 434 "smarty_internal_templateparser.y"
+    function yy_r54(){
+    $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -8]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor),array('key'=>$this->yystack[$this->yyidx + -5]->minor))));
+    }
+#line 2496 "smarty_internal_templateparser.php"
+#line 439 "smarty_internal_templateparser.y"
+    function yy_r55(){
+    $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array($this->yystack[$this->yyidx + -2]->minor),$this->yystack[$this->yyidx + -1]->minor))));
+    }
+#line 2501 "smarty_internal_templateparser.php"
+#line 443 "smarty_internal_templateparser.y"
+    function yy_r56(){
+    $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array($this->yystack[$this->yyidx + -3]->minor),$this->yystack[$this->yyidx + -2]->minor)),$this->yystack[$this->yyidx + -1]->minor)));
+    }
+#line 2506 "smarty_internal_templateparser.php"
+#line 448 "smarty_internal_templateparser.y"
+    function yy_r57(){
+    $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler);
+    }
+#line 2511 "smarty_internal_templateparser.php"
+#line 454 "smarty_internal_templateparser.y"
+    function yy_r58(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor.'close',array());
+    }
+#line 2516 "smarty_internal_templateparser.php"
+#line 458 "smarty_internal_templateparser.y"
+    function yy_r59(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor.'close',array(),array('modifier_list'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2521 "smarty_internal_templateparser.php"
+#line 463 "smarty_internal_templateparser.y"
+    function yy_r60(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor.'close',array(),array('object_methode'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2526 "smarty_internal_templateparser.php"
+#line 467 "smarty_internal_templateparser.y"
+    function yy_r61(){
+    $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor.'close',array(),array('object_methode'=>$this->yystack[$this->yyidx + -2]->minor, 'modifier_list'=>$this->yystack[$this->yyidx + -1]->minor));
+    }
+#line 2531 "smarty_internal_templateparser.php"
+#line 475 "smarty_internal_templateparser.y"
+    function yy_r62(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+    $this->_retvalue[] = $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2537 "smarty_internal_templateparser.php"
+#line 481 "smarty_internal_templateparser.y"
+    function yy_r63(){
+    $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2542 "smarty_internal_templateparser.php"
+#line 486 "smarty_internal_templateparser.y"
+    function yy_r64(){
+    $this->_retvalue = array();
+    }
+#line 2547 "smarty_internal_templateparser.php"
+#line 491 "smarty_internal_templateparser.y"
+    function yy_r65(){
+    if (preg_match('~^true$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'true');
+    } elseif (preg_match('~^false$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'false');
+    } elseif (preg_match('~^null$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'null');
+    } else {
+        $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>"'".$this->yystack[$this->yyidx + 0]->minor."'");
+    }
+    }
+#line 2560 "smarty_internal_templateparser.php"
+#line 503 "smarty_internal_templateparser.y"
+    function yy_r66(){
+    $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>$this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2565 "smarty_internal_templateparser.php"
+#line 511 "smarty_internal_templateparser.y"
+    function yy_r68(){
+    $this->_retvalue = "'".$this->yystack[$this->yyidx + 0]->minor."'";
+    }
+#line 2570 "smarty_internal_templateparser.php"
+#line 536 "smarty_internal_templateparser.y"
+    function yy_r73(){
+    $this->yystack[$this->yyidx + -2]->minor[]=$this->yystack[$this->yyidx + 0]->minor;
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+    }
+#line 2576 "smarty_internal_templateparser.php"
+#line 541 "smarty_internal_templateparser.y"
+    function yy_r74(){
+    $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -2]->minor, 'value'=>$this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2581 "smarty_internal_templateparser.php"
+#line 569 "smarty_internal_templateparser.y"
+    function yy_r79(){
+    $this->_retvalue = '$_smarty_tpl->getStreamVariable(\''. $this->yystack[$this->yyidx + -2]->minor .'://'. $this->yystack[$this->yyidx + 0]->minor . '\')';
+    }
+#line 2586 "smarty_internal_templateparser.php"
+#line 574 "smarty_internal_templateparser.y"
+    function yy_r80(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . trim($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2591 "smarty_internal_templateparser.php"
+#line 593 "smarty_internal_templateparser.y"
+    function yy_r84(){
+    $this->_retvalue = $this->compiler->compileTag('private_modifier',array(),array('value'=>$this->yystack[$this->yyidx + -1]->minor,'modifierlist'=>$this->yystack[$this->yyidx + 0]->minor));
+    }
+#line 2596 "smarty_internal_templateparser.php"
+#line 599 "smarty_internal_templateparser.y"
+    function yy_r85(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2601 "smarty_internal_templateparser.php"
+#line 603 "smarty_internal_templateparser.y"
+    function yy_r86(){
+    $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2606 "smarty_internal_templateparser.php"
+#line 607 "smarty_internal_templateparser.y"
+    function yy_r87(){
+    $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.',(array)'.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2611 "smarty_internal_templateparser.php"
+#line 615 "smarty_internal_templateparser.y"
+    function yy_r89(){
+    $this->_retvalue = '!('.$this->yystack[$this->yyidx + -2]->minor.' % '.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2616 "smarty_internal_templateparser.php"
+#line 619 "smarty_internal_templateparser.y"
+    function yy_r90(){
+    $this->_retvalue = '('.$this->yystack[$this->yyidx + -2]->minor.' % '.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2621 "smarty_internal_templateparser.php"
+#line 623 "smarty_internal_templateparser.y"
+    function yy_r91(){
+    $this->_retvalue = '!(1 & '.$this->yystack[$this->yyidx + -1]->minor.')';
+    }
+#line 2626 "smarty_internal_templateparser.php"
+#line 627 "smarty_internal_templateparser.y"
+    function yy_r92(){
+    $this->_retvalue = '(1 & '.$this->yystack[$this->yyidx + -1]->minor.')';
+    }
+#line 2631 "smarty_internal_templateparser.php"
+#line 631 "smarty_internal_templateparser.y"
+    function yy_r93(){
+    $this->_retvalue = '!(1 & '.$this->yystack[$this->yyidx + -2]->minor.' / '.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2636 "smarty_internal_templateparser.php"
+#line 635 "smarty_internal_templateparser.y"
+    function yy_r94(){
+    $this->_retvalue = '(1 & '.$this->yystack[$this->yyidx + -2]->minor.' / '.$this->yystack[$this->yyidx + 0]->minor.')';
+    }
+#line 2641 "smarty_internal_templateparser.php"
+#line 659 "smarty_internal_templateparser.y"
+    function yy_r100(){
+    $this->prefix_number++;
+    $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.$this->yystack[$this->yyidx + 0]->minor.';?>';
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.'$_tmp'.$this->prefix_number;
+    }
+#line 2648 "smarty_internal_templateparser.php"
+#line 668 "smarty_internal_templateparser.y"
+    function yy_r101(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -6]->minor.' ? '. $this->compileVariable("'".$this->yystack[$this->yyidx + -2]->minor."'") . ' : '.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2653 "smarty_internal_templateparser.php"
+#line 672 "smarty_internal_templateparser.y"
+    function yy_r102(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor.' ? '.$this->yystack[$this->yyidx + -2]->minor.' : '.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2658 "smarty_internal_templateparser.php"
+#line 687 "smarty_internal_templateparser.y"
+    function yy_r105(){
+    $this->_retvalue = '!'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2663 "smarty_internal_templateparser.php"
+#line 708 "smarty_internal_templateparser.y"
+    function yy_r110(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2668 "smarty_internal_templateparser.php"
+#line 712 "smarty_internal_templateparser.y"
+    function yy_r111(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.';
+    }
+#line 2673 "smarty_internal_templateparser.php"
+#line 716 "smarty_internal_templateparser.y"
+    function yy_r112(){
+    $this->_retvalue = '.'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2678 "smarty_internal_templateparser.php"
+#line 721 "smarty_internal_templateparser.y"
+    function yy_r113(){
+    if (preg_match('~^true$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = 'true';
+    } elseif (preg_match('~^false$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = 'false';
+    } elseif (preg_match('~^null$~i', $this->yystack[$this->yyidx + 0]->minor)) {
+        $this->_retvalue = 'null';
+    } else {
+        $this->_retvalue = "'".$this->yystack[$this->yyidx + 0]->minor."'";
+    }
+    }
+#line 2691 "smarty_internal_templateparser.php"
+#line 739 "smarty_internal_templateparser.y"
+    function yy_r115(){
+    $this->_retvalue = "(". $this->yystack[$this->yyidx + -1]->minor .")";
+    }
+#line 2696 "smarty_internal_templateparser.php"
+#line 754 "smarty_internal_templateparser.y"
+    function yy_r118(){
+    if (!$this->security || isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor]) || $this->smarty->security_policy->isTrustedStaticClass($this->yystack[$this->yyidx + -2]->minor, $this->compiler)) {
+        if (isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor])) {
+            $this->_retvalue = $this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor].'::'.$this->yystack[$this->yyidx + 0]->minor;
+        } else {
+            $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'::'.$this->yystack[$this->yyidx + 0]->minor;
+        }
+    } else {
+        $this->compiler->trigger_template_error ("static class '".$this->yystack[$this->yyidx + -2]->minor."' is undefined or not allowed by security setting");
+    }
+    }
+#line 2709 "smarty_internal_templateparser.php"
+#line 766 "smarty_internal_templateparser.y"
+    function yy_r119(){
+    if ($this->yystack[$this->yyidx + -2]->minor['var'] == '\'smarty\'') {
+        $this->_retvalue =  $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']).'::'.$this->yystack[$this->yyidx + 0]->minor;
+    } else {
+        $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + -2]->minor['var']).$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'].'::'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+    }
+#line 2718 "smarty_internal_templateparser.php"
+#line 775 "smarty_internal_templateparser.y"
+    function yy_r120(){
+    $this->prefix_number++;
+    $this->compiler->prefix_code[] = '<?php ob_start();?>'.$this->yystack[$this->yyidx + 0]->minor.'<?php $_tmp'.$this->prefix_number.'=ob_get_clean();?>';
+    $this->_retvalue = '$_tmp'.$this->prefix_number;
+    }
+#line 2725 "smarty_internal_templateparser.php"
+#line 790 "smarty_internal_templateparser.y"
+    function yy_r122(){
+    if ($this->yystack[$this->yyidx + 0]->minor['var'] == '\'smarty\'') {
+        $smarty_var = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']);
+        $this->_retvalue = $smarty_var;
+    } else {
+        // used for array reset,next,prev,end,current
+        $this->last_variable = $this->yystack[$this->yyidx + 0]->minor['var'];
+        $this->last_index = $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index'];
+        $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + 0]->minor['var']).$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index'];
+    }
+    }
+#line 2738 "smarty_internal_templateparser.php"
+#line 803 "smarty_internal_templateparser.y"
+    function yy_r123(){
+    $this->_retvalue = '$_smarty_tpl->tpl_vars['. $this->yystack[$this->yyidx + -2]->minor .']->'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2743 "smarty_internal_templateparser.php"
+#line 813 "smarty_internal_templateparser.y"
+    function yy_r125(){
+    $this->_retvalue = '$_smarty_tpl->getConfigVariable(\''. $this->yystack[$this->yyidx + -1]->minor .'\')';
+    }
+#line 2748 "smarty_internal_templateparser.php"
+#line 817 "smarty_internal_templateparser.y"
+    function yy_r126(){
+    $this->_retvalue = '$_smarty_tpl->getConfigVariable('. $this->yystack[$this->yyidx + -1]->minor .')';
+    }
+#line 2753 "smarty_internal_templateparser.php"
+#line 821 "smarty_internal_templateparser.y"
+    function yy_r127(){
+    $this->_retvalue = array('var'=>$this->yystack[$this->yyidx + -1]->minor, 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2758 "smarty_internal_templateparser.php"
+#line 834 "smarty_internal_templateparser.y"
+    function yy_r129(){
+    return;
+    }
+#line 2763 "smarty_internal_templateparser.php"
+#line 840 "smarty_internal_templateparser.y"
+    function yy_r130(){
+    $this->_retvalue = '['.$this->compileVariable($this->yystack[$this->yyidx + 0]->minor).']';
+    }
+#line 2768 "smarty_internal_templateparser.php"
+#line 844 "smarty_internal_templateparser.y"
+    function yy_r131(){
+    $this->_retvalue = '['.$this->compileVariable($this->yystack[$this->yyidx + -2]->minor).'->'.$this->yystack[$this->yyidx + 0]->minor.']';
+    }
+#line 2773 "smarty_internal_templateparser.php"
+#line 848 "smarty_internal_templateparser.y"
+    function yy_r132(){
+    $this->_retvalue = "['". $this->yystack[$this->yyidx + 0]->minor ."']";
+    }
+#line 2778 "smarty_internal_templateparser.php"
+#line 852 "smarty_internal_templateparser.y"
+    function yy_r133(){
+    $this->_retvalue = "[". $this->yystack[$this->yyidx + 0]->minor ."]";
+    }
+#line 2783 "smarty_internal_templateparser.php"
+#line 856 "smarty_internal_templateparser.y"
+    function yy_r134(){
+    $this->_retvalue = "[". $this->yystack[$this->yyidx + -1]->minor ."]";
+    }
+#line 2788 "smarty_internal_templateparser.php"
+#line 861 "smarty_internal_templateparser.y"
+    function yy_r135(){
+    $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\'][\'index\']').']';
+    }
+#line 2793 "smarty_internal_templateparser.php"
+#line 865 "smarty_internal_templateparser.y"
+    function yy_r136(){
+    $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -3]->minor.'\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\']').']';
+    }
+#line 2798 "smarty_internal_templateparser.php"
+#line 875 "smarty_internal_templateparser.y"
+    function yy_r138(){
+    $this->_retvalue = '[]';
+    }
+#line 2803 "smarty_internal_templateparser.php"
+#line 888 "smarty_internal_templateparser.y"
+    function yy_r140(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2808 "smarty_internal_templateparser.php"
+#line 893 "smarty_internal_templateparser.y"
+    function yy_r141(){
+    $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\'';
+    }
+#line 2813 "smarty_internal_templateparser.php"
+#line 898 "smarty_internal_templateparser.y"
+    function yy_r142(){
+    $this->_retvalue = '('.$this->yystack[$this->yyidx + -1]->minor.')';
+    }
+#line 2818 "smarty_internal_templateparser.php"
+#line 905 "smarty_internal_templateparser.y"
+    function yy_r143(){
+    if ($this->yystack[$this->yyidx + -1]->minor['var'] == '\'smarty\'') {
+        $this->_retvalue =  $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index']).$this->yystack[$this->yyidx + 0]->minor;
+    } else {
+        $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + -1]->minor['var']).$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'].$this->yystack[$this->yyidx + 0]->minor;
+    }
+    }
+#line 2827 "smarty_internal_templateparser.php"
+#line 914 "smarty_internal_templateparser.y"
+    function yy_r144(){
+    $this->_retvalue  = $this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2832 "smarty_internal_templateparser.php"
+#line 919 "smarty_internal_templateparser.y"
+    function yy_r145(){
+    $this->_retvalue  = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2837 "smarty_internal_templateparser.php"
+#line 924 "smarty_internal_templateparser.y"
+    function yy_r146(){
+    if ($this->security && substr($this->yystack[$this->yyidx + -1]->minor,0,1) == '_') {
+        $this->compiler->trigger_template_error (self::Err1);
+    }
+    $this->_retvalue = '->'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2845 "smarty_internal_templateparser.php"
+#line 931 "smarty_internal_templateparser.y"
+    function yy_r147(){
+    if ($this->security) {
+        $this->compiler->trigger_template_error (self::Err2);
+    }
+    $this->_retvalue = '->{'.$this->compileVariable($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor.'}';
+    }
+#line 2853 "smarty_internal_templateparser.php"
+#line 938 "smarty_internal_templateparser.y"
+    function yy_r148(){
+    if ($this->security) {
+        $this->compiler->trigger_template_error (self::Err2);
+    }
+    $this->_retvalue = '->{'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}';
+    }
+#line 2861 "smarty_internal_templateparser.php"
+#line 945 "smarty_internal_templateparser.y"
+    function yy_r149(){
+    if ($this->security) {
+        $this->compiler->trigger_template_error (self::Err2);
+    }
+    $this->_retvalue = '->{\''.$this->yystack[$this->yyidx + -4]->minor.'\'.'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}';
+    }
+#line 2869 "smarty_internal_templateparser.php"
+#line 953 "smarty_internal_templateparser.y"
+    function yy_r150(){
+    $this->_retvalue = '->'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2874 "smarty_internal_templateparser.php"
+#line 961 "smarty_internal_templateparser.y"
+    function yy_r151(){
+    if (!$this->security || $this->smarty->security_policy->isTrustedPhpFunction($this->yystack[$this->yyidx + -3]->minor, $this->compiler)) {
+        if (strcasecmp($this->yystack[$this->yyidx + -3]->minor,'isset') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor,'empty') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor,'array') === 0 || is_callable($this->yystack[$this->yyidx + -3]->minor)) {
+            $func_name = strtolower($this->yystack[$this->yyidx + -3]->minor);
+            if ($func_name == 'isset') {
+                if (count($this->yystack[$this->yyidx + -1]->minor) == 0) {
+                    $this->compiler->trigger_template_error ('Illegal number of paramer in "isset()"');
+                }
+                $par = implode(',',$this->yystack[$this->yyidx + -1]->minor);
+                if (strncasecmp($par,'$_smarty_tpl->getConfigVariable',strlen('$_smarty_tpl->getConfigVariable')) === 0) {
+                    $this->prefix_number++;
+                    $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.str_replace(')',', false)',$par).';?>';
+                    $isset_par = '$_tmp'.$this->prefix_number;
+                } else {
+                    $isset_par=str_replace("')->value","',null,true,false)->value",$par);
+                }
+                $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". $isset_par .")";
+            } elseif (in_array($func_name,array('empty','reset','current','end','prev','next'))){
+                if (count($this->yystack[$this->yyidx + -1]->minor) != 1) {
+                    $this->compiler->trigger_template_error ('Illegal number of paramer in "empty()"');
+                }
+                if ($func_name == 'empty') {
+                    $this->_retvalue = $func_name.'('.str_replace("')->value","',null,true,false)->value",$this->yystack[$this->yyidx + -1]->minor[0]).')';
+                } else {
+                    $this->_retvalue = $func_name.'('.$this->yystack[$this->yyidx + -1]->minor[0].')';
+                }
+            } else {
+                $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". implode(',',$this->yystack[$this->yyidx + -1]->minor) .")";
+            }
+        } else {
+            $this->compiler->trigger_template_error ("unknown function \"" . $this->yystack[$this->yyidx + -3]->minor . "\"");
+        }
+    }
+    }
+#line 2910 "smarty_internal_templateparser.php"
+#line 999 "smarty_internal_templateparser.y"
+    function yy_r152(){
+    if ($this->security && substr($this->yystack[$this->yyidx + -3]->minor,0,1) == '_') {
+        $this->compiler->trigger_template_error (self::Err1);
+    }
+    $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". implode(',',$this->yystack[$this->yyidx + -1]->minor) .")";
+    }
+#line 2918 "smarty_internal_templateparser.php"
+#line 1006 "smarty_internal_templateparser.y"
+    function yy_r153(){
+    if ($this->security) {
+        $this->compiler->trigger_template_error (self::Err2);
+    }
+    $this->prefix_number++;
+    $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.$this->compileVariable("'".$this->yystack[$this->yyidx + -3]->minor."'").';?>';
+    $this->_retvalue = '$_tmp'.$this->prefix_number.'('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')';
+    }
+#line 2928 "smarty_internal_templateparser.php"
+#line 1017 "smarty_internal_templateparser.y"
+    function yy_r154(){
+    $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array($this->yystack[$this->yyidx + 0]->minor));
+    }
+#line 2933 "smarty_internal_templateparser.php"
+#line 1034 "smarty_internal_templateparser.y"
+    function yy_r157(){
+    $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor)));
+    }
+#line 2938 "smarty_internal_templateparser.php"
+#line 1038 "smarty_internal_templateparser.y"
+    function yy_r158(){
+    $this->_retvalue = array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor));
+    }
+#line 2943 "smarty_internal_templateparser.php"
+#line 1046 "smarty_internal_templateparser.y"
+    function yy_r160(){
+    $this->_retvalue =  array($this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2948 "smarty_internal_templateparser.php"
+#line 1054 "smarty_internal_templateparser.y"
+    function yy_r161(){
+    $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 2953 "smarty_internal_templateparser.php"
+#line 1088 "smarty_internal_templateparser.y"
+    function yy_r168(){
+    $this->_retvalue = '$'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2958 "smarty_internal_templateparser.php"
+#line 1093 "smarty_internal_templateparser.y"
+    function yy_r169(){
+    $this->_retvalue = '$'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 2963 "smarty_internal_templateparser.php"
+#line 1099 "smarty_internal_templateparser.y"
+    function yy_r170(){
+    $this->_retvalue = '==';
+    }
+#line 2968 "smarty_internal_templateparser.php"
+#line 1103 "smarty_internal_templateparser.y"
+    function yy_r171(){
+    $this->_retvalue = '!=';
+    }
+#line 2973 "smarty_internal_templateparser.php"
+#line 1107 "smarty_internal_templateparser.y"
+    function yy_r172(){
+    $this->_retvalue = '>';
+    }
+#line 2978 "smarty_internal_templateparser.php"
+#line 1111 "smarty_internal_templateparser.y"
+    function yy_r173(){
+    $this->_retvalue = '<';
+    }
+#line 2983 "smarty_internal_templateparser.php"
+#line 1115 "smarty_internal_templateparser.y"
+    function yy_r174(){
+    $this->_retvalue = '>=';
+    }
+#line 2988 "smarty_internal_templateparser.php"
+#line 1119 "smarty_internal_templateparser.y"
+    function yy_r175(){
+    $this->_retvalue = '<=';
+    }
+#line 2993 "smarty_internal_templateparser.php"
+#line 1123 "smarty_internal_templateparser.y"
+    function yy_r176(){
+    $this->_retvalue = '===';
+    }
+#line 2998 "smarty_internal_templateparser.php"
+#line 1127 "smarty_internal_templateparser.y"
+    function yy_r177(){
+    $this->_retvalue = '!==';
+    }
+#line 3003 "smarty_internal_templateparser.php"
+#line 1131 "smarty_internal_templateparser.y"
+    function yy_r178(){
+    $this->_retvalue = '%';
+    }
+#line 3008 "smarty_internal_templateparser.php"
+#line 1135 "smarty_internal_templateparser.y"
+    function yy_r179(){
+    $this->_retvalue = '&&';
+    }
+#line 3013 "smarty_internal_templateparser.php"
+#line 1139 "smarty_internal_templateparser.y"
+    function yy_r180(){
+    $this->_retvalue = '||';
+    }
+#line 3018 "smarty_internal_templateparser.php"
+#line 1143 "smarty_internal_templateparser.y"
+    function yy_r181(){
+    $this->_retvalue = ' XOR ';
+    }
+#line 3023 "smarty_internal_templateparser.php"
+#line 1150 "smarty_internal_templateparser.y"
+    function yy_r182(){
+    $this->_retvalue = 'array('.$this->yystack[$this->yyidx + -1]->minor.')';
+    }
+#line 3028 "smarty_internal_templateparser.php"
+#line 1158 "smarty_internal_templateparser.y"
+    function yy_r184(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 3033 "smarty_internal_templateparser.php"
+#line 1166 "smarty_internal_templateparser.y"
+    function yy_r186(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'=>'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 3038 "smarty_internal_templateparser.php"
+#line 1170 "smarty_internal_templateparser.y"
+    function yy_r187(){
+    $this->_retvalue = '\''.$this->yystack[$this->yyidx + -2]->minor.'\'=>'.$this->yystack[$this->yyidx + 0]->minor;
+    }
+#line 3043 "smarty_internal_templateparser.php"
+#line 1182 "smarty_internal_templateparser.y"
+    function yy_r189(){
+    $this->_retvalue = "''";
+    }
+#line 3048 "smarty_internal_templateparser.php"
+#line 1186 "smarty_internal_templateparser.y"
+    function yy_r190(){
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor->to_smarty_php();
+    }
+#line 3053 "smarty_internal_templateparser.php"
+#line 1191 "smarty_internal_templateparser.y"
+    function yy_r191(){
+    $this->yystack[$this->yyidx + -1]->minor->append_subtree($this->yystack[$this->yyidx + 0]->minor);
+    $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+    }
+#line 3059 "smarty_internal_templateparser.php"
+#line 1196 "smarty_internal_templateparser.y"
+    function yy_r192(){
+    $this->_retvalue = new _smarty_doublequoted($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 3064 "smarty_internal_templateparser.php"
+#line 1200 "smarty_internal_templateparser.y"
+    function yy_r193(){
+    $this->_retvalue = new _smarty_code($this, $this->yystack[$this->yyidx + -1]->minor);
+    }
+#line 3069 "smarty_internal_templateparser.php"
+#line 1208 "smarty_internal_templateparser.y"
+    function yy_r195(){
+    $this->_retvalue = new _smarty_code($this, '$_smarty_tpl->tpl_vars[\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\']->value');
+    }
+#line 3074 "smarty_internal_templateparser.php"
+#line 1216 "smarty_internal_templateparser.y"
+    function yy_r197(){
+    $this->_retvalue = new _smarty_code($this, '('.$this->yystack[$this->yyidx + -1]->minor.')');
+    }
+#line 3079 "smarty_internal_templateparser.php"
+#line 1220 "smarty_internal_templateparser.y"
+    function yy_r198(){
+    $this->_retvalue = new _smarty_tag($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 3084 "smarty_internal_templateparser.php"
+#line 1224 "smarty_internal_templateparser.y"
+    function yy_r199(){
+    $this->_retvalue = new _smarty_dq_content($this, $this->yystack[$this->yyidx + 0]->minor);
+    }
+#line 3089 "smarty_internal_templateparser.php"
+
+    private $_retvalue;
+
+    function yy_reduce($yyruleno)
+    {
+        $yymsp = $this->yystack[$this->yyidx];
+        if (self::$yyTraceFILE && $yyruleno >= 0
+              && $yyruleno < count(self::$yyRuleName)) {
+            fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
+                self::$yyTracePrompt, $yyruleno,
+                self::$yyRuleName[$yyruleno]);
+        }
+
+        $this->_retvalue = $yy_lefthand_side = null;
+        if (array_key_exists($yyruleno, self::$yyReduceMap)) {
+            // call the action
+            $this->_retvalue = null;
+            $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+            $yy_lefthand_side = $this->_retvalue;
+        }
+        $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
+        $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
+        $this->yyidx -= $yysize;
+        for($i = $yysize; $i; $i--) {
+            // pop all of the right-hand side parameters
+            array_pop($this->yystack);
+        }
+        $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+        if ($yyact < self::YYNSTATE) {
+            if (!self::$yyTraceFILE && $yysize) {
+                $this->yyidx++;
+                $x = new TP_yyStackEntry;
+                $x->stateno = $yyact;
+                $x->major = $yygoto;
+                $x->minor = $yy_lefthand_side;
+                $this->yystack[$this->yyidx] = $x;
+            } else {
+                $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+            }
+        } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+            $this->yy_accept();
+        }
+    }
+
+    function yy_parse_failed()
+    {
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
+        }
+        while ($this->yyidx >= 0) {
+            $this->yy_pop_parser_stack();
+        }
+    }
+
+    function yy_syntax_error($yymajor, $TOKEN)
+    {
+#line 77 "smarty_internal_templateparser.y"
+
+    $this->internalError = true;
+    $this->yymajor = $yymajor;
+    $this->compiler->trigger_template_error();
+#line 3152 "smarty_internal_templateparser.php"
+    }
+
+    function yy_accept()
+    {
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
+        }
+        while ($this->yyidx >= 0) {
+            $stack = $this->yy_pop_parser_stack();
+        }
+#line 69 "smarty_internal_templateparser.y"
+
+    $this->successful = !$this->internalError;
+    $this->internalError = false;
+    $this->retvalue = $this->_retvalue;
+    //echo $this->retvalue."\n\n";
+#line 3170 "smarty_internal_templateparser.php"
+    }
+
+    function doParse($yymajor, $yytokenvalue)
+    {
+        $yyerrorhit = 0;   /* True if yymajor has invoked an error */
+
+        if ($this->yyidx === null || $this->yyidx < 0) {
+            $this->yyidx = 0;
+            $this->yyerrcnt = -1;
+            $x = new TP_yyStackEntry;
+            $x->stateno = 0;
+            $x->major = 0;
+            $this->yystack = array();
+            array_push($this->yystack, $x);
+        }
+        $yyendofinput = ($yymajor==0);
+
+        if (self::$yyTraceFILE) {
+            fprintf(self::$yyTraceFILE, "%sInput %s\n",
+                self::$yyTracePrompt, $this->yyTokenName[$yymajor]);
+        }
+
+        do {
+            $yyact = $this->yy_find_shift_action($yymajor);
+            if ($yymajor < self::YYERRORSYMBOL &&
+                  !$this->yy_is_expected_token($yymajor)) {
+                // force a syntax error
+                $yyact = self::YY_ERROR_ACTION;
+            }
+            if ($yyact < self::YYNSTATE) {
+                $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+                $this->yyerrcnt--;
+                if ($yyendofinput && $this->yyidx >= 0) {
+                    $yymajor = 0;
+                } else {
+                    $yymajor = self::YYNOCODE;
+                }
+            } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+                $this->yy_reduce($yyact - self::YYNSTATE);
+            } elseif ($yyact == self::YY_ERROR_ACTION) {
+                if (self::$yyTraceFILE) {
+                    fprintf(self::$yyTraceFILE, "%sSyntax Error!\n",
+                        self::$yyTracePrompt);
+                }
+                if (self::YYERRORSYMBOL) {
+                    if ($this->yyerrcnt < 0) {
+                        $this->yy_syntax_error($yymajor, $yytokenvalue);
+                    }
+                    $yymx = $this->yystack[$this->yyidx]->major;
+                    if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){
+                        if (self::$yyTraceFILE) {
+                            fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n",
+                                self::$yyTracePrompt, $this->yyTokenName[$yymajor]);
+                        }
+                        $this->yy_destructor($yymajor, $yytokenvalue);
+                        $yymajor = self::YYNOCODE;
+                    } else {
+                        while ($this->yyidx >= 0 &&
+                                 $yymx != self::YYERRORSYMBOL &&
+        ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
+                              ){
+                            $this->yy_pop_parser_stack();
+                        }
+                        if ($this->yyidx < 0 || $yymajor==0) {
+                            $this->yy_destructor($yymajor, $yytokenvalue);
+                            $this->yy_parse_failed();
+                            $yymajor = self::YYNOCODE;
+                        } elseif ($yymx != self::YYERRORSYMBOL) {
+                            $u2 = 0;
+                            $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+                        }
+                    }
+                    $this->yyerrcnt = 3;
+                    $yyerrorhit = 1;
+                } else {
+                    if ($this->yyerrcnt <= 0) {
+                        $this->yy_syntax_error($yymajor, $yytokenvalue);
+                    }
+                    $this->yyerrcnt = 3;
+                    $this->yy_destructor($yymajor, $yytokenvalue);
+                    if ($yyendofinput) {
+                        $this->yy_parse_failed();
+                    }
+                    $yymajor = self::YYNOCODE;
+                }
+            } else {
+                $this->yy_accept();
+                $yymajor = self::YYNOCODE;
+            }
+        } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+    }
+}
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_utility.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_utility.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_utility.php	(revision 345)
@@ -0,0 +1,810 @@
+<?php
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        smarty_internal_utility.php
+ * SVN:         $Id: $
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @version 3-SVN$Rev: 3286 $
+ */
+
+
+/**
+ * Utility class
+ *
+ * @package Smarty
+ * @subpackage Security
+ */
+class Smarty_Internal_Utility {
+
+    /**
+     * private constructor to prevent calls creation of new instances
+     */
+    private final function __construct()
+    {
+        // intentionally left blank
+    }
+
+    /**
+     * Compile all template files
+     *
+     * @param string $extension     template file name extension
+     * @param bool   $force_compile force all to recompile
+     * @param int    $time_limit    set maximum execution time
+     * @param int    $max_errors    set maximum allowed errors
+     * @param Smarty $smarty        Smarty instance
+     * @return integer number of template files compiled
+     */
+    public static function compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty)
+    {
+        // switch off time limit
+        if (function_exists('set_time_limit')) {
+            @set_time_limit($time_limit);
+        }
+        $smarty->force_compile = $force_compile;
+        $_count = 0;
+        $_error_count = 0;
+        // loop over array of template directories
+        foreach($smarty->getTemplateDir() as $_dir) {
+            $_compileDirs = new RecursiveDirectoryIterator($_dir);
+            $_compile = new RecursiveIteratorIterator($_compileDirs);
+            foreach ($_compile as $_fileinfo) {
+                if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
+                $_file = $_fileinfo->getFilename();
+                if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
+                if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
+                   $_template_file = $_file;
+                } else {
+                   $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
+                }
+                echo '<br>', $_dir, '---', $_template_file;
+                flush();
+                $_start_time = microtime(true);
+                try {
+                    $_tpl = $smarty->createTemplate($_template_file,null,null,null,false);
+                    if ($_tpl->mustCompile()) {
+                        $_tpl->compileTemplateSource();
+                        echo ' compiled in  ', microtime(true) - $_start_time, ' seconds';
+                        flush();
+                    } else {
+                        echo ' is up to date';
+                        flush();
+                    }
+                }
+                catch (Exception $e) {
+                    echo 'Error: ', $e->getMessage(), "<br><br>";
+                    $_error_count++;
+                }
+                // free memory
+                $smarty->template_objects = array();
+                $_tpl->smarty->template_objects = array();
+                $_tpl = null;
+                if ($max_errors !== null && $_error_count == $max_errors) {
+                    echo '<br><br>too many errors';
+                    exit();
+                }
+            }
+        }
+        return $_count;
+    }
+
+    /**
+     * Compile all config files
+     *
+     * @param string $extension     config file name extension
+     * @param bool   $force_compile force all to recompile
+     * @param int    $time_limit    set maximum execution time
+     * @param int    $max_errors    set maximum allowed errors
+     * @param Smarty $smarty        Smarty instance
+     * @return integer number of config files compiled
+     */
+    public static function compileAllConfig($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty)
+    {
+        // switch off time limit
+        if (function_exists('set_time_limit')) {
+            @set_time_limit($time_limit);
+        }
+        $smarty->force_compile = $force_compile;
+        $_count = 0;
+        $_error_count = 0;
+        // loop over array of template directories
+        foreach($smarty->getConfigDir() as $_dir) {
+            $_compileDirs = new RecursiveDirectoryIterator($_dir);
+            $_compile = new RecursiveIteratorIterator($_compileDirs);
+            foreach ($_compile as $_fileinfo) {
+                if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
+                $_file = $_fileinfo->getFilename();
+                if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
+                if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
+                    $_config_file = $_file;
+                } else {
+                    $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
+                }
+                echo '<br>', $_dir, '---', $_config_file;
+                flush();
+                $_start_time = microtime(true);
+                try {
+                    $_config = new Smarty_Internal_Config($_config_file, $smarty);
+                    if ($_config->mustCompile()) {
+                        $_config->compileConfigSource();
+                        echo ' compiled in  ', microtime(true) - $_start_time, ' seconds';
+                        flush();
+                    } else {
+                        echo ' is up to date';
+                        flush();
+                    }
+                }
+                catch (Exception $e) {
+                    echo 'Error: ', $e->getMessage(), "<br><br>";
+                    $_error_count++;
+                }
+                if ($max_errors !== null && $_error_count == $max_errors) {
+                    echo '<br><br>too many errors';
+                    exit();
+                }
+            }
+        }
+        return $_count;
+    }
+
+    /**
+     * Delete compiled template file
+     *
+     * @param string  $resource_name template name
+     * @param string  $compile_id    compile id
+     * @param integer $exp_time      expiration time
+     * @param Smarty  $smarty        Smarty instance
+     * @return integer number of template files deleted
+     */
+    public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty)
+    {
+        $_compile_dir = $smarty->getCompileDir();
+        $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+        $_dir_sep = $smarty->use_sub_dirs ? DS : '^';
+        if (isset($resource_name)) {
+            $_save_stat = $smarty->caching;
+            $smarty->caching = false;
+            $tpl = new $smarty->template_class($resource_name, $smarty);
+            $smarty->caching = $_save_stat;
+
+            // remove from template cache
+            $tpl->source; // have the template registered before unset()
+            if ($smarty->allow_ambiguous_resources) {
+                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+            } else {
+                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+            }
+            if (isset($_templateId[150])) {
+                $_templateId = sha1($_templateId);
+            }
+            unset($smarty->template_objects[$_templateId]);
+
+            if ($tpl->source->exists) {
+                 $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath));
+                 $_resource_part_1_length = strlen($_resource_part_1);
+            } else {
+                return 0;
+            }
+
+            $_resource_part_2 = str_replace('.php','.cache.php',$_resource_part_1);
+            $_resource_part_2_length = strlen($_resource_part_2);
+        } else {
+            $_resource_part = '';
+        }
+        $_dir = $_compile_dir;
+        if ($smarty->use_sub_dirs && isset($_compile_id)) {
+            $_dir .= $_compile_id . $_dir_sep;
+        }
+        if (isset($_compile_id)) {
+            $_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep;
+            $_compile_id_part_length = strlen($_compile_id_part);
+        }
+        $_count = 0;
+        try {
+            $_compileDirs = new RecursiveDirectoryIterator($_dir);
+        // NOTE: UnexpectedValueException thrown for PHP >= 5.3
+        } catch (Exception $e) {
+            return 0;
+        }
+        $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
+        foreach ($_compile as $_file) {
+            if (substr($_file->getBasename(), 0, 1) == '.' || strpos($_file, '.svn') !== false)
+                continue;
+
+            $_filepath = (string) $_file;
+
+            if ($_file->isDir()) {
+                if (!$_compile->isDot()) {
+                    // delete folder if empty
+                    @rmdir($_file->getPathname());
+                }
+            } else {
+                $unlink = false;
+                if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length)))
+                    && (!isset($resource_name)
+                        || (isset($_filepath[$_resource_part_1_length])
+                            && substr_compare($_filepath, $_resource_part_1, -$_resource_part_1_length, $_resource_part_1_length) == 0)
+                        || (isset($_filepath[$_resource_part_2_length])
+                            && substr_compare($_filepath, $_resource_part_2, -$_resource_part_2_length, $_resource_part_2_length) == 0))) {
+                    if (isset($exp_time)) {
+                        if (time() - @filemtime($_filepath) >= $exp_time) {
+                            $unlink = true;
+                        }
+                    } else {
+                        $unlink = true;
+                    }
+                }
+
+                if ($unlink && @unlink($_filepath)) {
+                    $_count++;
+                }
+            }
+        }
+        // clear compiled cache
+        Smarty_Resource::$sources = array();
+        Smarty_Resource::$compileds = array();
+        return $_count;
+    }
+
+    /**
+     * Return array of tag/attributes of all tags used by an template
+     *
+     * @param Smarty_Internal_Template $templae template object
+     * @return array of tag/attributes
+     */
+    public static function getTags(Smarty_Internal_Template $template)
+    {
+        $template->smarty->get_used_tags = true;
+        $template->compileTemplateSource();
+        return $template->used_tags;
+    }
+
+
+    /**
+     * diagnose Smarty setup
+     *
+     * If $errors is secified, the diagnostic report will be appended to the array, rather than being output.
+     *
+     * @param Smarty $smarty  Smarty instance to test
+     * @param array  $errors array to push results into rather than outputting them
+     * @return bool status, true if everything is fine, false else
+     */
+    public static function testInstall(Smarty $smarty, &$errors=null)
+    {
+        $status = true;
+
+        if ($errors === null) {
+            echo "<PRE>\n";
+            echo "Smarty Installation test...\n";
+            echo "Testing template directory...\n";
+        }
+
+        // test if all registered template_dir are accessible
+        foreach($smarty->getTemplateDir() as $template_dir) {
+            $_template_dir = $template_dir;
+            $template_dir = realpath($template_dir);
+            // resolve include_path or fail existance
+            if (!$template_dir) {
+                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
+                    // try PHP include_path
+                    if (($template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir)) !== false) {
+                        if ($errors === null) {
+                            echo "$template_dir is OK.\n";
+                        }
+
+                        continue;
+                    } else {
+                        $status = false;
+                        $message = "FAILED: $_template_dir does not exist (and couldn't be found in include_path either)";
+                        if ($errors === null) {
+                            echo $message . ".\n";
+                        } else {
+                            $errors['template_dir'] = $message;
+                        }
+
+                        continue;
+                    }
+                } else {
+                    $status = false;
+                    $message = "FAILED: $_template_dir does not exist";
+                    if ($errors === null) {
+                        echo $message . ".\n";
+                    } else {
+                        $errors['template_dir'] = $message;
+                    }
+
+                    continue;
+                }
+            }
+
+            if (!is_dir($template_dir)) {
+                $status = false;
+                $message = "FAILED: $template_dir is not a directory";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['template_dir'] = $message;
+                }
+            } elseif (!is_readable($template_dir)) {
+                $status = false;
+                $message = "FAILED: $template_dir is not readable";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['template_dir'] = $message;
+                }
+            } else {
+                if ($errors === null) {
+                    echo "$template_dir is OK.\n";
+                }
+            }
+        }
+
+
+        if ($errors === null) {
+            echo "Testing compile directory...\n";
+        }
+
+        // test if registered compile_dir is accessible
+        $__compile_dir = $smarty->getCompileDir();
+        $_compile_dir = realpath($__compile_dir);
+        if (!$_compile_dir) {
+            $status = false;
+            $message = "FAILED: {$__compile_dir} does not exist";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['compile_dir'] = $message;
+            }
+        } elseif (!is_dir($_compile_dir)) {
+            $status = false;
+            $message = "FAILED: {$_compile_dir} is not a directory";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['compile_dir'] = $message;
+            }
+        } elseif (!is_readable($_compile_dir)) {
+            $status = false;
+            $message = "FAILED: {$_compile_dir} is not readable";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['compile_dir'] = $message;
+            }
+        } elseif (!is_writable($_compile_dir)) {
+            $status = false;
+            $message = "FAILED: {$_compile_dir} is not writable";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['compile_dir'] = $message;
+            }
+        } else {
+            if ($errors === null) {
+                echo "{$_compile_dir} is OK.\n";
+            }
+        }
+
+
+        if ($errors === null) {
+            echo "Testing plugins directory...\n";
+        }
+
+        // test if all registered plugins_dir are accessible
+        // and if core plugins directory is still registered
+        $_core_plugins_dir = realpath(dirname(__FILE__) .'/../plugins');
+        $_core_plugins_available = false;
+        foreach($smarty->getPluginsDir() as $plugin_dir) {
+            $_plugin_dir = $plugin_dir;
+            $plugin_dir = realpath($plugin_dir);
+            // resolve include_path or fail existance
+            if (!$plugin_dir) {
+                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
+                    // try PHP include_path
+                    if (($plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir)) !== false) {
+                        if ($errors === null) {
+                            echo "$plugin_dir is OK.\n";
+                        }
+
+                        continue;
+                    } else {
+                        $status = false;
+                        $message = "FAILED: $_plugin_dir does not exist (and couldn't be found in include_path either)";
+                        if ($errors === null) {
+                            echo $message . ".\n";
+                        } else {
+                            $errors['plugins_dir'] = $message;
+                        }
+
+                        continue;
+                    }
+                } else {
+                    $status = false;
+                    $message = "FAILED: $_plugin_dir does not exist";
+                    if ($errors === null) {
+                        echo $message . ".\n";
+                    } else {
+                        $errors['plugins_dir'] = $message;
+                    }
+
+                    continue;
+                }
+            }
+
+            if (!is_dir($plugin_dir)) {
+                $status = false;
+                $message = "FAILED: $plugin_dir is not a directory";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['plugins_dir'] = $message;
+                }
+            } elseif (!is_readable($plugin_dir)) {
+                $status = false;
+                $message = "FAILED: $plugin_dir is not readable";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['plugins_dir'] = $message;
+                }
+            } elseif ($_core_plugins_dir && $_core_plugins_dir == realpath($plugin_dir)) {
+                $_core_plugins_available = true;
+                if ($errors === null) {
+                    echo "$plugin_dir is OK.\n";
+                }
+            } else {
+                if ($errors === null) {
+                    echo "$plugin_dir is OK.\n";
+                }
+            }
+        }
+        if (!$_core_plugins_available) {
+            $status = false;
+            $message = "WARNING: Smarty's own libs/plugins is not available";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } elseif (!isset($errors['plugins_dir'])) {
+                $errors['plugins_dir'] = $message;
+            }
+        }
+
+        if ($errors === null) {
+            echo "Testing cache directory...\n";
+        }
+
+
+        // test if all registered cache_dir is accessible
+        $__cache_dir = $smarty->getCacheDir();
+        $_cache_dir = realpath($__cache_dir);
+        if (!$_cache_dir) {
+            $status = false;
+            $message = "FAILED: {$__cache_dir} does not exist";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['cache_dir'] = $message;
+            }
+        } elseif (!is_dir($_cache_dir)) {
+            $status = false;
+            $message = "FAILED: {$_cache_dir} is not a directory";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['cache_dir'] = $message;
+            }
+        } elseif (!is_readable($_cache_dir)) {
+            $status = false;
+            $message = "FAILED: {$_cache_dir} is not readable";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['cache_dir'] = $message;
+            }
+        } elseif (!is_writable($_cache_dir)) {
+            $status = false;
+            $message = "FAILED: {$_cache_dir} is not writable";
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['cache_dir'] = $message;
+            }
+        } else {
+            if ($errors === null) {
+                echo "{$_cache_dir} is OK.\n";
+            }
+        }
+
+
+        if ($errors === null) {
+            echo "Testing configs directory...\n";
+        }
+
+        // test if all registered config_dir are accessible
+        foreach($smarty->getConfigDir() as $config_dir) {
+            $_config_dir = $config_dir;
+            $config_dir = realpath($config_dir);
+            // resolve include_path or fail existance
+            if (!$config_dir) {
+                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
+                    // try PHP include_path
+                    if (($config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir)) !== false) {
+                        if ($errors === null) {
+                            echo "$config_dir is OK.\n";
+                        }
+
+                        continue;
+                    } else {
+                        $status = false;
+                        $message = "FAILED: $_config_dir does not exist (and couldn't be found in include_path either)";
+                        if ($errors === null) {
+                            echo $message . ".\n";
+                        } else {
+                            $errors['config_dir'] = $message;
+                        }
+
+                        continue;
+                    }
+                } else {
+                    $status = false;
+                    $message = "FAILED: $_config_dir does not exist";
+                    if ($errors === null) {
+                        echo $message . ".\n";
+                    } else {
+                        $errors['config_dir'] = $message;
+                    }
+
+                    continue;
+                }
+            }
+
+            if (!is_dir($config_dir)) {
+                $status = false;
+                $message = "FAILED: $config_dir is not a directory";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['config_dir'] = $message;
+                }
+            } elseif (!is_readable($config_dir)) {
+                $status = false;
+                $message = "FAILED: $config_dir is not readable";
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['config_dir'] = $message;
+                }
+            } else {
+                if ($errors === null) {
+                    echo "$config_dir is OK.\n";
+                }
+            }
+        }
+
+
+        if ($errors === null) {
+            echo "Testing sysplugin files...\n";
+        }
+        // test if sysplugins are available
+        $source = SMARTY_SYSPLUGINS_DIR;
+        if (is_dir($source)) {
+            $expected = array(
+                "smarty_cacheresource.php" => true,
+                "smarty_cacheresource_custom.php" => true,
+                "smarty_cacheresource_keyvaluestore.php" => true,
+                "smarty_config_source.php" => true,
+                "smarty_internal_cacheresource_file.php" => true,
+                "smarty_internal_compile_append.php" => true,
+                "smarty_internal_compile_assign.php" => true,
+                "smarty_internal_compile_block.php" => true,
+                "smarty_internal_compile_break.php" => true,
+                "smarty_internal_compile_call.php" => true,
+                "smarty_internal_compile_capture.php" => true,
+                "smarty_internal_compile_config_load.php" => true,
+                "smarty_internal_compile_continue.php" => true,
+                "smarty_internal_compile_debug.php" => true,
+                "smarty_internal_compile_eval.php" => true,
+                "smarty_internal_compile_extends.php" => true,
+                "smarty_internal_compile_for.php" => true,
+                "smarty_internal_compile_foreach.php" => true,
+                "smarty_internal_compile_function.php" => true,
+                "smarty_internal_compile_if.php" => true,
+                "smarty_internal_compile_include.php" => true,
+                "smarty_internal_compile_include_php.php" => true,
+                "smarty_internal_compile_insert.php" => true,
+                "smarty_internal_compile_ldelim.php" => true,
+                "smarty_internal_compile_nocache.php" => true,
+                "smarty_internal_compile_private_block_plugin.php" => true,
+                "smarty_internal_compile_private_function_plugin.php" => true,
+                "smarty_internal_compile_private_modifier.php" => true,
+                "smarty_internal_compile_private_object_block_function.php" => true,
+                "smarty_internal_compile_private_object_function.php" => true,
+                "smarty_internal_compile_private_print_expression.php" => true,
+                "smarty_internal_compile_private_registered_block.php" => true,
+                "smarty_internal_compile_private_registered_function.php" => true,
+                "smarty_internal_compile_private_special_variable.php" => true,
+                "smarty_internal_compile_rdelim.php" => true,
+                "smarty_internal_compile_section.php" => true,
+                "smarty_internal_compile_setfilter.php" => true,
+                "smarty_internal_compile_while.php" => true,
+                "smarty_internal_compilebase.php" => true,
+                "smarty_internal_config.php" => true,
+                "smarty_internal_config_file_compiler.php" => true,
+                "smarty_internal_configfilelexer.php" => true,
+                "smarty_internal_configfileparser.php" => true,
+                "smarty_internal_data.php" => true,
+                "smarty_internal_debug.php" => true,
+                "smarty_internal_filter_handler.php" => true,
+                "smarty_internal_function_call_handler.php" => true,
+                "smarty_internal_get_include_path.php" => true,
+                "smarty_internal_nocache_insert.php" => true,
+                "smarty_internal_parsetree.php" => true,
+                "smarty_internal_resource_eval.php" => true,
+                "smarty_internal_resource_extends.php" => true,
+                "smarty_internal_resource_file.php" => true,
+                "smarty_internal_resource_registered.php" => true,
+                "smarty_internal_resource_stream.php" => true,
+                "smarty_internal_resource_string.php" => true,
+                "smarty_internal_smartytemplatecompiler.php" => true,
+                "smarty_internal_template.php" => true,
+                "smarty_internal_templatebase.php" => true,
+                "smarty_internal_templatecompilerbase.php" => true,
+                "smarty_internal_templatelexer.php" => true,
+                "smarty_internal_templateparser.php" => true,
+                "smarty_internal_utility.php" => true,
+                "smarty_internal_write_file.php" => true,
+                "smarty_resource.php" => true,
+                "smarty_resource_custom.php" => true,
+                "smarty_resource_recompiled.php" => true,
+                "smarty_resource_uncompiled.php" => true,
+                "smarty_security.php" => true,
+            );
+            $iterator = new DirectoryIterator($source);
+            foreach ($iterator as $file) {
+                if (!$file->isDot()) {
+                    $filename = $file->getFilename();
+                    if (isset($expected[$filename])) {
+                        unset($expected[$filename]);
+                    }
+                }
+            }
+            if ($expected) {
+                $status = false;
+                $message = "FAILED: files missing from libs/sysplugins: ". join(', ', array_keys($expected));
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['sysplugins'] = $message;
+                }
+            } elseif ($errors === null) {
+                echo "... OK\n";
+            }
+        } else {
+            $status = false;
+            $message = "FAILED: ". SMARTY_SYSPLUGINS_DIR .' is not a directory';
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['sysplugins_dir_constant'] = $message;
+            }
+        }
+
+        if ($errors === null) {
+            echo "Testing plugin files...\n";
+        }
+        // test if core plugins are available
+        $source = SMARTY_PLUGINS_DIR;
+        if (is_dir($source)) {
+            $expected = array(
+                "block.textformat.php" => true,
+                "function.counter.php" => true,
+                "function.cycle.php" => true,
+                "function.fetch.php" => true,
+                "function.html_checkboxes.php" => true,
+                "function.html_image.php" => true,
+                "function.html_options.php" => true,
+                "function.html_radios.php" => true,
+                "function.html_select_date.php" => true,
+                "function.html_select_time.php" => true,
+                "function.html_table.php" => true,
+                "function.mailto.php" => true,
+                "function.math.php" => true,
+                "modifier.capitalize.php" => true,
+                "modifier.date_format.php" => true,
+                "modifier.debug_print_var.php" => true,
+                "modifier.escape.php" => true,
+                "modifier.regex_replace.php" => true,
+                "modifier.replace.php" => true,
+                "modifier.spacify.php" => true,
+                "modifier.truncate.php" => true,
+                "modifiercompiler.cat.php" => true,
+                "modifiercompiler.count_characters.php" => true,
+                "modifiercompiler.count_paragraphs.php" => true,
+                "modifiercompiler.count_sentences.php" => true,
+                "modifiercompiler.count_words.php" => true,
+                "modifiercompiler.default.php" => true,
+                "modifiercompiler.escape.php" => true,
+                "modifiercompiler.from_charset.php" => true,
+                "modifiercompiler.indent.php" => true,
+                "modifiercompiler.lower.php" => true,
+                "modifiercompiler.noprint.php" => true,
+                "modifiercompiler.string_format.php" => true,
+                "modifiercompiler.strip.php" => true,
+                "modifiercompiler.strip_tags.php" => true,
+                "modifiercompiler.to_charset.php" => true,
+                "modifiercompiler.unescape.php" => true,
+                "modifiercompiler.upper.php" => true,
+                "modifiercompiler.wordwrap.php" => true,
+                "outputfilter.trimwhitespace.php" => true,
+                "shared.escape_special_chars.php" => true,
+                "shared.literal_compiler_param.php" => true,
+                "shared.make_timestamp.php" => true,
+                "shared.mb_str_replace.php" => true,
+                "shared.mb_unicode.php" => true,
+                "shared.mb_wordwrap.php" => true,
+                "variablefilter.htmlspecialchars.php" => true,
+            );
+            $iterator = new DirectoryIterator($source);
+            foreach ($iterator as $file) {
+                if (!$file->isDot()) {
+                    $filename = $file->getFilename();
+                    if (isset($expected[$filename])) {
+                        unset($expected[$filename]);
+                    }
+                }
+            }
+            if ($expected) {
+                $status = false;
+                $message = "FAILED: files missing from libs/plugins: ". join(', ', array_keys($expected));
+                if ($errors === null) {
+                    echo $message . ".\n";
+                } else {
+                    $errors['plugins'] = $message;
+                }
+            } elseif ($errors === null) {
+                echo "... OK\n";
+            }
+        } else {
+            $status = false;
+            $message = "FAILED: ". SMARTY_PLUGINS_DIR .' is not a directory';
+            if ($errors === null) {
+                echo $message . ".\n";
+            } else {
+                $errors['plugins_dir_constant'] = $message;
+            }
+        }
+
+        if ($errors === null) {
+            echo "Tests complete.\n";
+            echo "</PRE>\n";
+        }
+
+        return $status;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_write_file.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_write_file.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_write_file.php	(revision 345)
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Smarty write file plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Monte Ohrt
+ */
+
+/**
+ * Smarty Internal Write File Class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Write_File {
+
+    /**
+     * Writes file in a safe way to disk
+     *
+     * @param string $_filepath complete filepath
+     * @param string $_contents file content
+     * @param Smarty $smarty    smarty instance
+     * @return boolean true
+     */
+    public static function writeFile($_filepath, $_contents, Smarty $smarty)
+    {
+        $_error_reporting = error_reporting();
+        error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
+        if ($smarty->_file_perms !== null) {
+            $old_umask = umask(0);
+        }
+
+        $_dirpath = dirname($_filepath);
+        // if subdirs, create dir structure
+        if ($_dirpath !== '.' && !file_exists($_dirpath)) {
+            mkdir($_dirpath, $smarty->_dir_perms === null ? 0777 : $smarty->_dir_perms, true);
+        }
+
+        // write to tmp file, then move to overt file lock race condition
+        $_tmp_file = $_dirpath . DS . uniqid('wrt');
+        if (!file_put_contents($_tmp_file, $_contents)) {
+            error_reporting($_error_reporting);
+            throw new SmartyException("unable to write file {$_tmp_file}");
+            return false;
+        }
+
+        // remove original file
+        @unlink($_filepath);
+
+        // rename tmp file
+        $success = rename($_tmp_file, $_filepath);
+        if (!$success) {
+            error_reporting($_error_reporting);
+            throw new SmartyException("unable to write file {$_filepath}");
+            return false;
+        }
+
+        if ($smarty->_file_perms !== null) {
+            // set file permissions
+            chmod($_filepath, $smarty->_file_perms);
+            umask($old_umask);
+        }
+        error_reporting($_error_reporting);
+        return true;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource.php	(revision 345)
@@ -0,0 +1,822 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ *
+ * Base implementation for resource plugins
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource {
+    /**
+     * cache for Smarty_Template_Source instances
+     * @var array
+     */
+    public static $sources = array();
+    /**
+     * cache for Smarty_Template_Compiled instances
+     * @var array
+     */
+    public static $compileds = array();
+    /**
+     * cache for Smarty_Resource instances
+     * @var array
+     */
+    public static $resources = array();
+    /**
+     * resource types provided by the core
+     * @var array
+     */
+    protected static $sysplugins = array(
+        'file' => true,
+        'string' => true,
+        'extends' => true,
+        'stream' => true,
+        'eval' => true,
+        'php' => true
+    );
+
+    /**
+     * Name of the Class to compile this resource's contents with
+     * @var string
+     */
+    public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler';
+
+    /**
+     * Name of the Class to tokenize this resource's contents with
+     * @var string
+     */
+    public $template_lexer_class = 'Smarty_Internal_Templatelexer';
+
+    /**
+     * Name of the Class to parse this resource's contents with
+     * @var string
+     */
+    public $template_parser_class = 'Smarty_Internal_Templateparser';
+
+    /**
+     * Load template's source into current template object
+     *
+     * {@internal The loaded source is assigned to $_template->source->content directly.}}
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public abstract function getContent(Smarty_Template_Source $source);
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source source object
+     * @param Smarty_Internal_Template $_template     template object
+     */
+    public abstract function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null);
+
+    /**
+     * populate Source Object with timestamp and exists from Resource
+     *
+     * @param Smarty_Template_Source $source source object
+     */
+    public function populateTimestamp(Smarty_Template_Source $source)
+    {
+        // intentionally left blank
+    }
+
+
+    /**
+     * modify resource_name according to resource handlers specifications
+     *
+     * @param Smarty $smarty        Smarty instance
+     * @param string $resource_name resource_name to make unique
+     * @return string unique resource name
+     */
+    protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
+    {
+        return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name;
+    }
+
+    /**
+     * populate Compiled Object with compiled filepath
+     *
+     * @param Smarty_Template_Compiled $compiled  compiled object
+     * @param Smarty_Internal_Template $_template template object
+     */
+    public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
+    {
+        $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
+        $_filepath = $compiled->source->uid;
+        // if use_sub_dirs, break file into directories
+        if ($_template->smarty->use_sub_dirs) {
+            $_filepath = substr($_filepath, 0, 2) . DS
+             . substr($_filepath, 2, 2) . DS
+             . substr($_filepath, 4, 2) . DS
+             . $_filepath;
+        }
+        $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
+        if (isset($_compile_id)) {
+            $_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
+        }
+        // caching token
+        if ($_template->caching) {
+            $_cache = '.cache';
+        } else {
+            $_cache = '';
+        }
+        $_compile_dir = $_template->smarty->getCompileDir();
+        // set basename if not specified
+        $_basename = $this->getBasename($compiled->source);
+        if ($_basename === null) {
+            $_basename = basename( preg_replace('![^\w\/]+!', '_', $compiled->source->name) );
+        }
+        // separate (optional) basename by dot
+        if ($_basename) {
+            $_basename = '.' . $_basename;
+        }
+
+        $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php';
+    }
+
+    /**
+     * build template filepath by traversing the template_dir array
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @return string fully qualified filepath
+     * @throws SmartyException if default template handler is registered but not callable
+     */
+    protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $file = $source->name;
+        if ($source instanceof Smarty_Config_Source) {
+            $_directories = $source->smarty->getConfigDir();
+            $_default_handler = $source->smarty->default_config_handler_func;
+        } else {
+            $_directories = $source->smarty->getTemplateDir();
+            $_default_handler = $source->smarty->default_template_handler_func;
+        }
+
+        // go relative to a given template?
+        $_file_is_dotted = $file[0] == '.' && ($file[1] == '.' || $file[1] == '/' || $file[1] == "\\");
+        if ($_template && $_template->parent instanceof Smarty_Internal_Template && $_file_is_dotted) {
+            if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) {
+                throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'");
+            }
+            $file = dirname($_template->parent->source->filepath) . DS . $file;
+            $_file_exact_match = true;
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
+                // the path gained from the parent template is relative to the current working directory
+                // as expansions (like include_path) have already been done
+                $file = getcwd() . DS . $file;
+            }
+        }
+
+        // resolve relative path
+        if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
+            $_was_relative_prefix = $file[0] == '.' ? substr($file, 0, strpos($file, '|')) : null;
+            $_path = DS . trim($file, '/\\');
+            $_was_relative = true;
+        } else {
+            $_path = $file;
+        }
+        // don't we all just love windows?
+        $_path = str_replace('\\', '/', $_path);
+        // resolve simples
+        $_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
+        // resolve parents
+        while (true) {
+            $_parent = strpos($_path, '/../');
+            if ($_parent === false) {
+                break;
+            } else if ($_parent === 0) {
+                $_path = substr($_path, 3);
+                break;
+            }
+            $_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
+            if ($_pos === false) {
+                // don't we all just love windows?
+                $_pos = $_parent;
+            }
+            $_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
+        }
+        if (DS != '/') {
+            // don't we all just love windows?
+            $_path = str_replace('/', '\\', $_path);
+        }
+        // revert to relative
+        if (isset($_was_relative)) {
+            if (isset($_was_relative_prefix)){
+                $_path = $_was_relative_prefix . $_path;
+            } else {
+                $_path = substr($_path, 1);
+            }
+        }
+
+        // this is only required for directories
+        $file = rtrim($_path, '/\\');
+
+        // files relative to a template only get one shot
+        if (isset($_file_exact_match)) {
+            return $this->fileExists($source, $file) ? $file : false;
+        }
+
+        // template_dir index?
+        if (preg_match('#^\[(?P<key>[^\]]+)\](?P<file>.+)$#', $file, $match)) {
+            $_directory = null;
+            // try string indexes
+            if (isset($_directories[$match['key']])) {
+                $_directory = $_directories[$match['key']];
+            } else if (is_numeric($match['key'])) {
+                // try numeric index
+                $match['key'] = (int) $match['key'];
+                if (isset($_directories[$match['key']])) {
+                    $_directory = $_directories[$match['key']];
+                } else {
+                    // try at location index
+                    $keys = array_keys($_directories);
+                    $_directory = $_directories[$keys[$match['key']]];
+                }
+            }
+
+            if ($_directory) {
+                $_file = substr($file, strpos($file, ']') + 1);
+                $_filepath = $_directory . $_file;
+                if ($this->fileExists($source, $_filepath)) {
+                    return $_filepath;
+                }
+            }
+        }
+
+        // relative file name?
+        if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
+            foreach ($_directories as $_directory) {
+                $_filepath = $_directory . $file;
+                if ($this->fileExists($source, $_filepath)) {
+                    return $_filepath;
+                }
+                if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
+                    // try PHP include_path
+                    if (($_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath)) !== false) {
+                        if ($this->fileExists($source, $_filepath)) {
+                            return $_filepath;
+                        }
+                    }
+                }
+            }
+        }
+
+        // try absolute filepath
+        if ($this->fileExists($source, $file)) {
+            return $file;
+        }
+
+        // no tpl file found
+        if ($_default_handler) {
+            if (!is_callable($_default_handler)) {
+                if ($source instanceof Smarty_Config_Source) {
+                    throw new SmartyException("Default config handler not callable");
+                } else {
+                    throw new SmartyException("Default template handler not callable");
+                }
+            }
+            $_return = call_user_func_array($_default_handler,
+                array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty));
+            if (is_string($_return)) {
+                $source->timestamp = @filemtime($_return);
+                $source->exists = !!$source->timestamp;
+                return $_return;
+            } elseif ($_return === true) {
+                $source->content = $_content;
+                $source->timestamp = $_timestamp;
+                $source->exists = true;
+                return $_filepath;
+            }
+        }
+
+        // give up
+        return false;
+    }
+
+    /**
+     * test is file exists and save timestamp
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param string $file file name
+     * @return bool  true if file exists
+     */
+    protected function fileExists(Smarty_Template_Source $source, $file)
+    {
+        $source->timestamp = @filemtime($file);
+        return $source->exists = !!$source->timestamp;
+
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    protected function getBasename(Smarty_Template_Source $source)
+    {
+        return null;
+    }
+
+    /**
+     * Load Resource Handler
+     *
+     * @param Smarty $smarty    smarty object
+     * @param string $type      name of the resource
+     * @return Smarty_Resource Resource Handler
+     */
+    public static function load(Smarty $smarty, $type)
+    {
+        // try smarty's cache
+        if (isset($smarty->_resource_handlers[$type])) {
+            return $smarty->_resource_handlers[$type];
+        }
+
+        // try registered resource
+        if (isset($smarty->registered_resources[$type])) {
+            if ($smarty->registered_resources[$type] instanceof Smarty_Resource) {
+                $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type];
+                // note registered to smarty is not kept unique!
+                return $smarty->_resource_handlers[$type];
+            }
+
+            if (!isset(self::$resources['registered'])) {
+                self::$resources['registered'] = new Smarty_Internal_Resource_Registered();
+            }
+            if (!isset($smarty->_resource_handlers[$type])) {
+                $smarty->_resource_handlers[$type] = self::$resources['registered'];
+            }
+
+            return $smarty->_resource_handlers[$type];
+        }
+
+        // try sysplugins dir
+        if (isset(self::$sysplugins[$type])) {
+            if (!isset(self::$resources[$type])) {
+                $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type);
+                self::$resources[$type] = new $_resource_class();
+            }
+            return $smarty->_resource_handlers[$type] = self::$resources[$type];
+        }
+
+        // try plugins dir
+        $_resource_class = 'Smarty_Resource_' . ucfirst($type);
+        if ($smarty->loadPlugin($_resource_class)) {
+            if (isset(self::$resources[$type])) {
+                return $smarty->_resource_handlers[$type] = self::$resources[$type];
+            }
+
+            if (class_exists($_resource_class, false)) {
+                self::$resources[$type] = new $_resource_class();
+                return $smarty->_resource_handlers[$type] = self::$resources[$type];
+            } else {
+                $smarty->registerResource($type, array(
+                    "smarty_resource_{$type}_source",
+                    "smarty_resource_{$type}_timestamp",
+                    "smarty_resource_{$type}_secure",
+                    "smarty_resource_{$type}_trusted"
+                ));
+
+                // give it another try, now that the resource is registered properly
+                return self::load($smarty, $type);
+            }
+        }
+
+        // try streams
+        $_known_stream = stream_get_wrappers();
+        if (in_array($type, $_known_stream)) {
+            // is known stream
+            if (is_object($smarty->security_policy)) {
+                $smarty->security_policy->isTrustedStream($type);
+            }
+            if (!isset(self::$resources['stream'])) {
+                self::$resources['stream'] = new Smarty_Internal_Resource_Stream();
+            }
+            return $smarty->_resource_handlers[$type] = self::$resources['stream'];
+        }
+
+        // TODO: try default_(template|config)_handler
+
+        // give up
+        throw new SmartyException("Unkown resource type '{$type}'");
+    }
+
+    /**
+     * extract resource_type and resource_name from template_resource and config_resource
+     *
+     * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including).
+     * @param string  $resource_name    template_resource or config_resource to parse
+     * @param string  $default_resource the default resource_type defined in $smarty
+     * @param string &$name             the parsed resource name
+     * @param string &$type             the parsed resource type
+     * @return void
+     */
+    protected static function parseResourceName($resource_name, $default_resource, &$name, &$type)
+    {
+        $parts = explode(':', $resource_name, 2);
+        if (!isset($parts[1]) || !isset($parts[0][1])) {
+            // no resource given, use default
+            // or single character before the colon is not a resource type, but part of the filepath
+            $type = $default_resource;
+            $name = $resource_name;
+        } else {
+            $type = $parts[0];
+            $name = $parts[1];
+        }
+    }
+
+
+    /**
+     * modify resource_name according to resource handlers specifications
+     *
+     * @param Smarty $smarty        Smarty instance
+     * @param string $resource_name resource_name to make unique
+     * @return string unique resource name
+     */
+
+    /**
+     * modify template_resource according to resource handlers specifications
+     *
+     * @param string $smarty            Smarty instance
+     * @param string $template_resource template_resource to extracate resource handler and name of
+     * @return string unique resource name
+     */
+    public static function getUniqueTemplateName($smarty, $template_resource)
+    {
+        self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type);
+        // TODO: optimize for Smarty's internal resource types
+        $resource = Smarty_Resource::load($smarty, $type);
+        return $resource->buildUniqueResourceName($smarty, $name);
+    }
+
+    /**
+     * initialize Source Object for given resource
+     *
+     * Either [$_template] or [$smarty, $template_resource] must be specified
+     *
+     * @param Smarty_Internal_Template $_template         template object
+     * @param Smarty                   $smarty            smarty object
+     * @param string                   $template_resource resource identifier
+     * @return Smarty_Template_Source Source Object
+     */
+    public static function source(Smarty_Internal_Template $_template=null, Smarty $smarty=null, $template_resource=null)
+    {
+        if ($_template) {
+            $smarty = $_template->smarty;
+            $template_resource = $_template->template_resource;
+        }
+
+        // parse resource_name, load resource handler, identify unique resource name
+        self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type);
+        $resource = Smarty_Resource::load($smarty, $type);
+        $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name);
+
+        // check runtime cache
+        $_cache_key = 'template|' . $unique_resource_name;
+        if (isset(self::$sources[$_cache_key])) {
+            return self::$sources[$_cache_key];
+        }
+
+        // create source
+        $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name, $unique_resource_name);
+        $resource->populate($source, $_template);
+
+        // runtime cache
+        self::$sources[$_cache_key] = $source;
+        return $source;
+    }
+
+    /**
+     * initialize Config Source Object for given resource
+     *
+     * @param Smarty_Internal_Config $_config config object
+     * @return Smarty_Config_Source Source Object
+     */
+    public static function config(Smarty_Internal_Config $_config)
+    {
+        static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true);
+        $config_resource = $_config->config_resource;
+        $smarty = $_config->smarty;
+
+        // parse resource_name
+        self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type);
+
+        // make sure configs are not loaded via anything smarty can't handle
+        if (isset($_incompatible_resources[$type])) {
+            throw new SmartyException ("Unable to use resource '{$type}' for config");
+        }
+
+        // load resource handler, identify unique resource name
+        $resource = Smarty_Resource::load($smarty, $type);
+        $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name);
+
+        // check runtime cache
+        $_cache_key = 'config|' . $unique_resource_name;
+        if (isset(self::$sources[$_cache_key])) {
+            return self::$sources[$_cache_key];
+        }
+
+        // create source
+        $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name);
+        $resource->populate($source, null);
+
+        // runtime cache
+        self::$sources[$_cache_key] = $source;
+        return $source;
+    }
+
+}
+
+/**
+ * Smarty Resource Data Object
+ *
+ * Meta Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ *
+ * @property integer $timestamp Source Timestamp
+ * @property boolean $exists    Source Existance
+ * @property boolean $template  Extended Template reference
+ * @property string  $content   Source Content
+ */
+class Smarty_Template_Source {
+
+    /**
+     * Name of the Class to compile this resource's contents with
+     * @var string
+     */
+    public $compiler_class = null;
+
+    /**
+     * Name of the Class to tokenize this resource's contents with
+     * @var string
+     */
+    public $template_lexer_class = null;
+
+    /**
+     * Name of the Class to parse this resource's contents with
+     * @var string
+     */
+    public $template_parser_class = null;
+
+    /**
+     * Unique Template ID
+     * @var string
+     */
+    public $uid = null;
+
+    /**
+     * Template Resource (Smarty_Internal_Template::$template_resource)
+     * @var string
+     */
+    public $resource = null;
+
+    /**
+     * Resource Type
+     * @var string
+     */
+    public $type = null;
+
+    /**
+     * Resource Name
+     * @var string
+     */
+    public $name = null;
+
+    /**
+     * Unique Resource Name
+     * @var string
+     */
+    public $unique_resource = null;
+
+    /**
+     * Source Filepath
+     * @var string
+     */
+    public $filepath = null;
+
+    /**
+     * Source is bypassing compiler
+     * @var boolean
+     */
+    public $uncompiled = null;
+
+    /**
+     * Source must be recompiled on every occasion
+     * @var boolean
+     */
+    public $recompiled = null;
+
+    /**
+     * The Components an extended template is made of
+     * @var array
+     */
+    public $components = null;
+
+    /**
+     * Resource Handler
+     * @var Smarty_Resource
+     */
+    public $handler = null;
+
+    /**
+     * Smarty instance
+     * @var Smarty
+     */
+    public $smarty = null;
+
+    /**
+     * create Source Object container
+     *
+     * @param Smarty_Resource $handler          Resource Handler this source object communicates with
+     * @param Smarty          $smarty           Smarty instance this source object belongs to
+     * @param string          $resource         full template_resource
+     * @param string          $type             type of resource
+     * @param string          $name             resource name
+     * @param string          $unique_resource  unqiue resource name
+     */
+    public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource)
+    {
+        $this->handler = $handler; // Note: prone to circular references
+
+        $this->compiler_class = $handler->compiler_class;
+        $this->template_lexer_class = $handler->template_lexer_class;
+        $this->template_parser_class = $handler->template_parser_class;
+        $this->uncompiled = $this->handler instanceof Smarty_Resource_Uncompiled;
+        $this->recompiled = $this->handler instanceof Smarty_Resource_Recompiled;
+
+        $this->smarty = $smarty;
+        $this->resource = $resource;
+        $this->type = $type;
+        $this->name = $name;
+        $this->unique_resource = $unique_resource;
+    }
+
+    /**
+     * get a Compiled Object of this source
+     *
+     * @param Smarty_Internal_Template $_template template objet
+     * @return Smarty_Template_Compiled compiled object
+     */
+    public function getCompiled(Smarty_Internal_Template $_template)
+    {
+        // check runtime cache
+        $_cache_key = $this->unique_resource . '#' . $_template->compile_id;
+        if (isset(Smarty_Resource::$compileds[$_cache_key])) {
+            return Smarty_Resource::$compileds[$_cache_key];
+        }
+
+        $compiled = new Smarty_Template_Compiled($this);
+        $this->handler->populateCompiledFilepath($compiled, $_template);
+        $compiled->timestamp = @filemtime($compiled->filepath);
+        $compiled->exists = !!$compiled->timestamp;
+
+        // runtime cache
+        Smarty_Resource::$compileds[$_cache_key] = $compiled;
+
+        return $compiled;
+    }
+
+    /**
+     * render the uncompiled source
+     *
+     * @param Smarty_Internal_Template $_template template object
+     */
+    public function renderUncompiled(Smarty_Internal_Template $_template)
+    {
+        return $this->handler->renderUncompiled($this, $_template);
+    }
+
+    /**
+     * <<magic>> Generic Setter.
+     *
+     * @param string $property_name valid: timestamp, exists, content, template
+     * @param mixed  $value        new value (is not checked)
+     * @throws SmartyException if $property_name is not valid
+     */
+    public function __set($property_name, $value)
+    {
+        switch ($property_name) {
+            // regular attributes
+            case 'timestamp':
+            case 'exists':
+            case 'content':
+            // required for extends: only
+            case 'template':
+                $this->$property_name = $value;
+                break;
+
+            default:
+                throw new SmartyException("invalid source property '$property_name'.");
+        }
+    }
+
+    /**
+     * <<magic>> Generic getter.
+     *
+     * @param string $property_name valid: timestamp, exists, content
+     * @return mixed
+     * @throws SmartyException if $property_name is not valid
+     */
+    public function __get($property_name)
+    {
+        switch ($property_name) {
+            case 'timestamp':
+            case 'exists':
+                $this->handler->populateTimestamp($this);
+                return $this->$property_name;
+
+            case 'content':
+                return $this->content = $this->handler->getContent($this);
+
+            default:
+                throw new SmartyException("source property '$property_name' does not exist.");
+        }
+    }
+
+}
+
+/**
+ * Smarty Resource Data Object
+ *
+ * Meta Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ *
+ * @property string $content compiled content
+ */
+class Smarty_Template_Compiled {
+
+    /**
+     * Compiled Filepath
+     * @var string
+     */
+    public $filepath = null;
+
+    /**
+     * Compiled Timestamp
+     * @var integer
+     */
+    public $timestamp = null;
+
+    /**
+     * Compiled Existance
+     * @var boolean
+     */
+    public $exists = false;
+
+    /**
+     * Compiled Content Loaded
+     * @var boolean
+     */
+    public $loaded = false;
+
+    /**
+     * Template was compiled
+     * @var boolean
+     */
+    public $isCompiled = false;
+
+    /**
+     * Source Object
+     * @var Smarty_Template_Source
+     */
+    public $source = null;
+
+    /**
+     * Metadata properties
+     *
+     * populated by Smarty_Internal_Template::decodeProperties()
+     * @var array
+     */
+    public $_properties = null;
+
+    /**
+     * create Compiled Object container
+     *
+     * @param Smarty_Template_Source $source source object this compiled object belongs to
+     */
+    public function __construct(Smarty_Template_Source $source)
+    {
+        $this->source = $source;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_custom.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_custom.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_custom.php	(revision 345)
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ *
+ * Wrapper Implementation for custom resource plugins
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Custom extends Smarty_Resource {
+
+    /**
+     * fetch template and its modification time from data source
+     *
+     * @param string  $name    template name
+     * @param string  &$source template source
+     * @param integer &$mtime  template modification timestamp (epoch)
+     */
+    protected abstract function fetch($name, &$source, &$mtime);
+
+    /**
+     * Fetch template's modification timestamp from data source
+     *
+     * {@internal implementing this method is optional.
+     *  Only implement it if modification times can be accessed faster than loading the complete template source.}}
+     *
+     * @param string $name template name
+     * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+     */
+    protected function fetchTimestamp($name)
+    {
+        return null;
+    }
+
+    /**
+     * populate Source Object with meta data from Resource
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     */
+    public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+    {
+        $source->filepath = strtolower($source->type . ':' . $source->name);
+        $source->uid = sha1($source->type . ':' . $source->name);
+
+        $mtime = $this->fetchTimestamp($source->name);
+        if ($mtime !== null) {
+            $source->timestamp = $mtime;
+        } else {
+            $this->fetch($source->name, $content, $timestamp);
+            $source->timestamp = isset($timestamp) ? $timestamp : false;
+            if( isset($content) )
+                $source->content = $content;
+        }
+        $source->exists = !!$source->timestamp;
+    }
+
+    /**
+     * Load template's source into current template object
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string template source
+     * @throws SmartyException if source cannot be loaded
+     */
+    public function getContent(Smarty_Template_Source $source)
+    {
+        $this->fetch($source->name, $content, $timestamp);
+        if (isset($content)) {
+            return $content;
+        }
+
+        throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+    }
+
+    /**
+     * Determine basename for compiled filename
+     *
+     * @param Smarty_Template_Source $source source object
+     * @return string resource's basename
+     */
+    protected function getBasename(Smarty_Template_Source $source)
+    {
+        return basename($source->name);
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_recompiled.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_recompiled.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_recompiled.php	(revision 345)
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ *
+ * Base implementation for resource plugins that don't compile cache
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Recompiled extends Smarty_Resource {
+
+    /**
+     * populate Compiled Object with compiled filepath
+     *
+     * @param Smarty_Template_Compiled $compiled compiled object
+     * @param Smarty_Internal_Template $_template template object
+     * @return void
+     */
+    public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
+    {
+        $compiled->filepath = false;
+        $compiled->timestamp = false;
+        $compiled->exists = false;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_uncompiled.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_uncompiled.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_resource_uncompiled.php	(revision 345)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ *
+ * Base implementation for resource plugins that don't use the compiler
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Uncompiled extends Smarty_Resource {
+
+    /**
+     * Render and output the template (without using the compiler)
+     *
+     * @param Smarty_Template_Source   $source    source object
+     * @param Smarty_Internal_Template $_template template object
+     * @throws SmartyException on failure
+     */
+    public abstract function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template);
+
+    /**
+     * populate compiled object with compiled filepath
+     *
+     * @param Smarty_Template_Compiled $compiled  compiled object
+     * @param Smarty_Internal_Template $_template template object (is ignored)
+     */
+    public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
+    {
+        $compiled->filepath = false;
+        $compiled->timestamp = false;
+        $compiled->exists = false;
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_security.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_security.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_security.php	(revision 345)
@@ -0,0 +1,459 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage Security
+ * @author Uwe Tews
+ */
+ 
+/*
+ * FIXME: Smarty_Security API
+ *      - getter and setter instead of public properties would allow cultivating an internal cache properly
+ *      - current implementation of isTrustedResourceDir() assumes that Smarty::$template_dir and Smarty::$config_dir are immutable
+ *        the cache is killed every time either of the variables change. That means that two distinct Smarty objects with differing
+ *        $template_dir or $config_dir should NOT share the same Smarty_Security instance, 
+ *        as this would lead to (severe) performance penalty! how should this be handled? 
+ */
+
+/**
+ * This class does contain the security settings
+ */
+class Smarty_Security {
+
+    /**
+     * This determines how Smarty handles "<?php ... ?>" tags in templates.
+     * possible values:
+     * <ul>
+     *   <li>Smarty::PHP_PASSTHRU -> echo PHP tags as they are</li>
+     *   <li>Smarty::PHP_QUOTE    -> escape tags as entities</li>
+     *   <li>Smarty::PHP_REMOVE   -> remove php tags</li>
+     *   <li>Smarty::PHP_ALLOW    -> execute php tags</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    public $php_handling = Smarty::PHP_PASSTHRU;
+    /**
+     * This is the list of template directories that are considered secure.
+     * $template_dir is in this list implicitly.
+     *
+     * @var array
+     */
+    public $secure_dir = array();
+    /**
+     * This is an array of directories where trusted php scripts reside.
+     * {@link $security} is disabled during their inclusion/execution.
+     *
+     * @var array
+     */
+    public $trusted_dir = array();
+    /**
+     * List of regular expressions (PCRE) that include trusted URIs
+     *
+     * @var array
+     */
+    public $trusted_uri = array();
+    /**
+     * This is an array of trusted static classes.
+     *
+     * If empty access to all static classes is allowed.
+     * If set to 'none' none is allowed.
+     * @var array
+     */
+    public $static_classes = array();
+    /**
+     * This is an array of trusted PHP functions.
+     *
+     * If empty all functions are allowed.
+     * To disable all PHP functions set $php_functions = null.
+     * @var array
+     */
+    public $php_functions = array(
+        'isset', 'empty',
+        'count', 'sizeof',
+        'in_array', 'is_array',
+        'time',
+        'nl2br',
+    );
+    /**
+     * This is an array of trusted PHP modifers.
+     *
+     * If empty all modifiers are allowed.
+     * To disable all modifier set $modifiers = null.
+     * @var array
+     */
+    public $php_modifiers = array(
+        'escape',
+        'count'
+    );
+    /**
+     * This is an array of allowed tags.
+     *
+     * If empty no restriction by allowed_tags.
+     * @var array
+     */
+    public $allowed_tags = array();
+    /**
+     * This is an array of disabled tags.
+     *
+     * If empty no restriction by disabled_tags.
+     * @var array
+     */
+    public $disabled_tags = array();
+    /**
+     * This is an array of allowed modifier plugins.
+     *
+     * If empty no restriction by allowed_modifiers.
+     * @var array
+     */
+    public $allowed_modifiers = array();
+    /**
+     * This is an array of disabled modifier plugins.
+     *
+     * If empty no restriction by disabled_modifiers.
+     * @var array
+     */
+    public $disabled_modifiers = array();
+    /**
+     * This is an array of trusted streams.
+     *
+     * If empty all streams are allowed.
+     * To disable all streams set $streams = null.
+     * @var array
+     */
+    public $streams = array('file');
+    /**
+     * + flag if constants can be accessed from template
+     * @var boolean
+     */
+    public $allow_constants = true;
+    /**
+     * + flag if super globals can be accessed from template
+     * @var boolean
+     */
+    public $allow_super_globals = true;
+
+    /**
+     * Cache for $resource_dir lookups
+     * @var array
+     */
+    protected $_resource_dir = null;
+    /**
+     * Cache for $template_dir lookups
+     * @var array
+     */
+    protected $_template_dir = null;
+    /**
+     * Cache for $config_dir lookups
+     * @var array
+     */
+    protected $_config_dir = null;
+    /**
+     * Cache for $secure_dir lookups
+     * @var array
+     */
+    protected $_secure_dir = null;
+    /**
+     * Cache for $php_resource_dir lookups
+     * @var array
+     */
+    protected $_php_resource_dir = null;
+    /**
+     * Cache for $trusted_dir lookups
+     * @var array
+     */
+    protected $_trusted_dir = null;
+    
+    
+    /**
+     * @param Smarty $smarty
+     */
+    public function __construct($smarty)
+    {
+        $this->smarty = $smarty;
+    }
+    
+    /**
+     * Check if PHP function is trusted.
+     *
+     * @param string $function_name
+     * @param object $compiler compiler object
+     * @return boolean true if function is trusted
+     * @throws SmartyCompilerException if php function is not trusted
+     */
+    public function isTrustedPhpFunction($function_name, $compiler)
+    {
+        if (isset($this->php_functions) && (empty($this->php_functions) || in_array($function_name, $this->php_functions))) {
+            return true;
+        }
+
+        $compiler->trigger_template_error("PHP function '{$function_name}' not allowed by security setting");
+        return false; // should not, but who knows what happens to the compiler in the future?
+    }
+
+    /**
+     * Check if static class is trusted.
+     *
+     * @param string $class_name
+     * @param object $compiler compiler object
+     * @return boolean true if class is trusted
+     * @throws SmartyCompilerException if static class is not trusted
+     */
+    public function isTrustedStaticClass($class_name, $compiler)
+    {
+        if (isset($this->static_classes) && (empty($this->static_classes) || in_array($class_name, $this->static_classes))) {
+            return true;
+        }
+
+        $compiler->trigger_template_error("access to static class '{$class_name}' not allowed by security setting");
+        return false; // should not, but who knows what happens to the compiler in the future?
+    }
+
+    /**
+     * Check if PHP modifier is trusted.
+     *
+     * @param string $modifier_name
+     * @param object $compiler compiler object
+     * @return boolean true if modifier is trusted
+     * @throws SmartyCompilerException if modifier is not trusted
+     */
+    public function isTrustedPhpModifier($modifier_name, $compiler)
+    {
+        if (isset($this->php_modifiers) && (empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))) {
+            return true;
+        }
+
+        $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting");
+        return false; // should not, but who knows what happens to the compiler in the future?
+    }
+
+    /**
+     * Check if tag is trusted.
+     *
+     * @param string $tag_name
+     * @param object $compiler compiler object
+     * @return boolean true if tag is trusted
+     * @throws SmartyCompilerException if modifier is not trusted
+     */
+    public function isTrustedTag($tag_name, $compiler)
+    {
+        // check for internal always required tags
+        if (in_array($tag_name, array('assign', 'call', 'private_filter', 'private_block_plugin', 'private_function_plugin', 'private_object_block_function',
+                    'private_object_function', 'private_registered_function', 'private_registered_block', 'private_special_variable', 'private_print_expression', 'private_modifier'))) {
+            return true;
+        }
+        // check security settings
+        if (empty($this->allowed_tags)) {
+            if (empty($this->disabled_tags) || !in_array($tag_name, $this->disabled_tags)) {
+                return true;
+            } else {
+                $compiler->trigger_template_error("tag '{$tag_name}' disabled by security setting", $compiler->lex->taglineno);
+            }
+        } else if (in_array($tag_name, $this->allowed_tags) && !in_array($tag_name, $this->disabled_tags)) {
+            return true;
+        } else {
+            $compiler->trigger_template_error("tag '{$tag_name}' not allowed by security setting", $compiler->lex->taglineno);
+        }
+        return false; // should not, but who knows what happens to the compiler in the future?
+    }
+
+    /**
+     * Check if modifier plugin is trusted.
+     *
+     * @param string $modifier_name
+     * @param object $compiler compiler object
+     * @return boolean true if tag is trusted
+     * @throws SmartyCompilerException if modifier is not trusted
+     */
+    public function isTrustedModifier($modifier_name, $compiler)
+    {
+        // check for internal always allowed modifier
+        if (in_array($modifier_name, array('default'))) {
+            return true;
+        }
+        // check security settings
+        if (empty($this->allowed_modifiers)) {
+            if (empty($this->disabled_modifiers) || !in_array($modifier_name, $this->disabled_modifiers)) {
+                return true;
+            } else {
+                $compiler->trigger_template_error("modifier '{$modifier_name}' disabled by security setting", $compiler->lex->taglineno);
+            }
+        } else if (in_array($modifier_name, $this->allowed_modifiers) && !in_array($modifier_name, $this->disabled_modifiers)) {
+            return true;
+        } else {
+            $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting", $compiler->lex->taglineno);
+        }
+        return false; // should not, but who knows what happens to the compiler in the future?
+    }
+
+    /**
+     * Check if stream is trusted.
+     *
+     * @param string $stream_name
+     * @return boolean true if stream is trusted
+     * @throws SmartyException if stream is not trusted
+     */
+    public function isTrustedStream($stream_name)
+    {
+        if (isset($this->streams) && (empty($this->streams) || in_array($stream_name, $this->streams))) {
+            return true;
+        }
+
+        throw new SmartyException("stream '{$stream_name}' not allowed by security setting");
+    }
+
+    /**
+     * Check if directory of file resource is trusted.
+     *
+     * @param string $filepath
+     * @return boolean true if directory is trusted
+     * @throws SmartyException if directory is not trusted
+     */
+    public function isTrustedResourceDir($filepath)
+    {
+        $_template = false;
+        $_config = false;
+        $_secure = false;
+
+        $_template_dir = $this->smarty->getTemplateDir();
+        $_config_dir = $this->smarty->getConfigDir();
+
+        // check if index is outdated
+        if ((!$this->_template_dir || $this->_template_dir !== $_template_dir)
+                || (!$this->_config_dir || $this->_config_dir !== $_config_dir)
+                || (!empty($this->secure_dir) && (!$this->_secure_dir || $this->_secure_dir !== $this->secure_dir))
+        ) {
+            $this->_resource_dir = array();
+            $_template = true;
+            $_config = true;
+            $_secure = !empty($this->secure_dir);
+        }
+
+        // rebuild template dir index
+        if ($_template) {
+            $this->_template_dir = $_template_dir;
+            foreach ($_template_dir as $directory) {
+                $directory = realpath($directory);
+                $this->_resource_dir[$directory] = true;
+            }
+        }
+
+        // rebuild config dir index
+        if ($_config) {
+            $this->_config_dir = $_config_dir;
+            foreach ($_config_dir as $directory) {
+                $directory = realpath($directory);
+                $this->_resource_dir[$directory] = true;
+            }
+        }
+
+        // rebuild secure dir index
+        if ($_secure) {
+            $this->_secure_dir = $this->secure_dir;
+            foreach ((array) $this->secure_dir as $directory) {
+                $directory = realpath($directory);
+                $this->_resource_dir[$directory] = true;
+            }
+        }
+
+        $_filepath = realpath($filepath);
+        $directory = dirname($_filepath);
+        $_directory = array();
+        while (true) {
+            // remember the directory to add it to _resource_dir in case we're successful
+            $_directory[] = $directory;
+            // test if the directory is trusted
+            if (isset($this->_resource_dir[$directory])) {
+                // merge sub directories of current $directory into _resource_dir to speed up subsequent lookups
+                $this->_resource_dir = array_merge($this->_resource_dir, $_directory);
+                return true;
+            }
+            // abort if we've reached root
+            if (($pos = strrpos($directory, DS)) === false || !isset($directory[1])) {
+                break;
+            }
+            // bubble up one level
+            $directory = substr($directory, 0, $pos);
+        }
+
+        // give up
+        throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
+    }
+    
+    /**
+     * Check if URI (e.g. {fetch} or {html_image}) is trusted
+     *
+     * To simplify things, isTrustedUri() resolves all input to "{$PROTOCOL}://{$HOSTNAME}".
+     * So "http://username:password@hello.world.example.org:8080/some-path?some=query-string"
+     * is reduced to "http://hello.world.example.org" prior to applying the patters from {@link $trusted_uri}.
+     * @param string $uri 
+     * @return boolean true if URI is trusted
+     * @throws SmartyException if URI is not trusted
+     * @uses $trusted_uri for list of patterns to match against $uri
+     */
+    public function isTrustedUri($uri)
+    {
+        $_uri = parse_url($uri);
+        if (!empty($_uri['scheme']) && !empty($_uri['host'])) {
+            $_uri = $_uri['scheme'] . '://' . $_uri['host'];
+            foreach ($this->trusted_uri as $pattern) {
+                if (preg_match($pattern, $_uri)) {
+                    return true;
+                }
+            }
+        }
+        
+        throw new SmartyException("URI '{$uri}' not allowed by security setting");
+    }
+    
+    /**
+     * Check if directory of file resource is trusted.
+     *
+     * @param string $filepath
+     * @return boolean true if directory is trusted
+     * @throws SmartyException if PHP directory is not trusted
+     */
+    public function isTrustedPHPDir($filepath)
+    {
+        if (empty($this->trusted_dir)) {
+            throw new SmartyException("directory '{$filepath}' not allowed by security setting (no trusted_dir specified)");
+        }
+
+        // check if index is outdated
+        if (!$this->_trusted_dir || $this->_trusted_dir !== $this->trusted_dir) {
+            $this->_php_resource_dir = array();
+
+            $this->_trusted_dir = $this->trusted_dir;
+            foreach ((array) $this->trusted_dir as $directory) {
+                $directory = realpath($directory);
+                $this->_php_resource_dir[$directory] = true;
+            }
+        }
+
+        $_filepath = realpath($filepath);
+        $directory = dirname($_filepath);
+        $_directory = array();
+        while (true) {
+            // remember the directory to add it to _resource_dir in case we're successful
+            $_directory[] = $directory;
+            // test if the directory is trusted
+            if (isset($this->_php_resource_dir[$directory])) {
+                // merge sub directories of current $directory into _resource_dir to speed up subsequent lookups
+                $this->_php_resource_dir = array_merge($this->_php_resource_dir, $_directory);
+                return true;
+            }
+            // abort if we've reached root
+            if (($pos = strrpos($directory, DS)) === false || !isset($directory[2])) {
+                break;
+            }
+            // bubble up one level
+            $directory = substr($directory, 0, $pos);
+        }
+
+        throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
+    }
+
+}
+
+?>
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Autoloader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Autoloader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Autoloader.php	(revision 345)
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Autoloads Twig classes.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Autoloader
+{
+    /**
+     * Registers Twig_Autoloader as an SPL autoloader.
+     */
+    static public function register()
+    {
+        ini_set('unserialize_callback_func', 'spl_autoload_call');
+        spl_autoload_register(array(new self, 'autoload'));
+    }
+
+    /**
+     * Handles autoloading of classes.
+     *
+     * @param  string  $class  A class name.
+     *
+     * @return boolean Returns true if the class has been loaded
+     */
+    static public function autoload($class)
+    {
+        if (0 !== strpos($class, 'Twig')) {
+            return;
+        }
+
+        if (file_exists($file = dirname(__FILE__).'/../'.str_replace('_', '/', $class).'.php')) {
+            require $file;
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Compiler.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Compiler.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Compiler.php	(revision 345)
@@ -0,0 +1,220 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Compiles a node to PHP code.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Compiler implements Twig_CompilerInterface
+{
+    protected $lastLine;
+    protected $source;
+    protected $indentation;
+    protected $env;
+
+    /**
+     * Constructor.
+     *
+     * @param Twig_Environment $env The twig environment instance
+     */
+    public function __construct(Twig_Environment $env)
+    {
+        $this->env = $env;
+    }
+
+    /**
+     * Returns the environment instance related to this compiler.
+     *
+     * @return Twig_Environment The environment instance
+     */
+    public function getEnvironment()
+    {
+        return $this->env;
+    }
+
+    /**
+     * Gets the current PHP code after compilation.
+     *
+     * @return string The PHP code
+     */
+    public function getSource()
+    {
+        return $this->source;
+    }
+
+    /**
+     * Compiles a node.
+     *
+     * @param Twig_NodeInterface $node   The node to compile
+     * @param integer            $indent The current indentation
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function compile(Twig_NodeInterface $node, $indentation = 0)
+    {
+        $this->lastLine = null;
+        $this->source = '';
+        $this->indentation = $indentation;
+
+        $node->compile($this);
+
+        return $this;
+    }
+
+    public function subcompile(Twig_NodeInterface $node, $raw = true)
+    {
+        if (false === $raw)
+        {
+            $this->addIndentation();
+        }
+
+        $node->compile($this);
+
+        return $this;
+    }
+
+    /**
+     * Adds a raw string to the compiled code.
+     *
+     * @param  string $string The string
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function raw($string)
+    {
+        $this->source .= $string;
+
+        return $this;
+    }
+
+    /**
+     * Writes a string to the compiled code by adding indentation.
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function write()
+    {
+        $strings = func_get_args();
+        foreach ($strings as $string) {
+            $this->addIndentation();
+            $this->source .= $string;
+        }
+
+        return $this;
+    }
+
+    public function addIndentation()
+    {
+        $this->source .= str_repeat(' ', $this->indentation * 4);
+
+        return $this;
+    }
+
+    /**
+     * Adds a quoted string to the compiled code.
+     *
+     * @param  string $string The string
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function string($value)
+    {
+        $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\"));
+
+        return $this;
+    }
+
+    /**
+     * Returns a PHP representation of a given value.
+     *
+     * @param  mixed $value The value to convert
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function repr($value)
+    {
+        if (is_int($value) || is_float($value)) {
+            $this->raw($value);
+        } else if (null === $value) {
+            $this->raw('null');
+        } else if (is_bool($value)) {
+            $this->raw($value ? 'true' : 'false');
+        } else if (is_array($value)) {
+            $this->raw('array(');
+            $i = 0;
+            foreach ($value as $key => $value) {
+                if ($i++) {
+                    $this->raw(', ');
+                }
+                $this->repr($key);
+                $this->raw(' => ');
+                $this->repr($value);
+            }
+            $this->raw(')');
+        } else {
+            $this->string($value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds debugging information.
+     *
+     * @param Twig_NodeInterface $node The related twig node
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function addDebugInfo(Twig_NodeInterface $node)
+    {
+        if ($node->getLine() != $this->lastLine) {
+            $this->lastLine = $node->getLine();
+            $this->write("// line {$node->getLine()}\n");
+        }
+
+        return $this;
+    }
+
+    /**
+     * Indents the generated code.
+     *
+     * @param integer $indent The number of indentation to add
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function indent($step = 1)
+    {
+        $this->indentation += $step;
+
+        return $this;
+    }
+
+    /**
+     * Outdents the generated code.
+     *
+     * @param integer $indent The number of indentation to remove
+     *
+     * @return Twig_Compiler The current compiler instance
+     */
+    public function outdent($step = 1)
+    {
+        $this->indentation -= $step;
+
+        if ($this->indentation < 0) {
+            throw new Twig_Error('Unable to call outdent() as the indentation would become negative');
+        }
+
+        return $this;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/CompilerInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/CompilerInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/CompilerInterface.php	(revision 345)
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by compiler classes.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_CompilerInterface
+{
+    /**
+     * Compiles a node.
+     *
+     * @param  Twig_NodeInterface $node The node to compile
+     *
+     * @return Twig_CompilerInterface The current compiler instance
+     */
+    function compile(Twig_NodeInterface $node);
+
+    /**
+     * Gets the current PHP code after compilation.
+     *
+     * @return string The PHP code
+     */
+    function getSource();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Environment.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Environment.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Environment.php	(revision 345)
@@ -0,0 +1,906 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stores the Twig configuration.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Environment
+{
+    const VERSION = '1.0.0-RC2';
+
+    protected $charset;
+    protected $loader;
+    protected $debug;
+    protected $autoReload;
+    protected $cache;
+    protected $lexer;
+    protected $parser;
+    protected $compiler;
+    protected $baseTemplateClass;
+    protected $extensions;
+    protected $parsers;
+    protected $visitors;
+    protected $filters;
+    protected $tests;
+    protected $functions;
+    protected $globals;
+    protected $runtimeInitialized;
+    protected $loadedTemplates;
+    protected $strictVariables;
+    protected $unaryOperators;
+    protected $binaryOperators;
+    protected $templateClassPrefix = '__TwigTemplate_';
+    protected $functionCallbacks;
+    protected $filterCallbacks;
+
+    /**
+     * Constructor.
+     *
+     * Available options:
+     *
+     *  * debug: When set to `true`, the generated templates have a __toString()
+     *           method that you can use to display the generated nodes (default to
+     *           false).
+     *
+     *  * charset: The charset used by the templates (default to utf-8).
+     *
+     *  * base_template_class: The base template class to use for generated
+     *                         templates (default to Twig_Template).
+     *
+     *  * cache: An absolute path where to store the compiled templates, or
+     *           false to disable compilation cache (default)
+     *
+     *  * auto_reload: Whether to reload the template is the original source changed.
+     *                 If you don't provide the auto_reload option, it will be
+     *                 determined automatically base on the debug value.
+     *
+     *  * strict_variables: Whether to ignore invalid variables in templates
+     *                      (default to false).
+     *
+     *  * autoescape: Whether to enable auto-escaping (default to true);
+     *
+     *  * optimizations: A flag that indicates which optimizations to apply
+     *                   (default to -1 which means that all optimizations are enabled;
+     *                   set it to 0 to disable)
+     *
+     * @param Twig_LoaderInterface   $loader  A Twig_LoaderInterface instance
+     * @param array                  $options An array of options
+     */
+    public function __construct(Twig_LoaderInterface $loader = null, $options = array())
+    {
+        if (null !== $loader) {
+            $this->setLoader($loader);
+        }
+
+        $options = array_merge(array(
+            'debug'               => false,
+            'charset'             => 'UTF-8',
+            'base_template_class' => 'Twig_Template',
+            'strict_variables'    => false,
+            'autoescape'          => true,
+            'cache'               => false,
+            'auto_reload'         => null,
+            'optimizations'       => -1,
+        ), $options);
+
+        $this->debug              = (bool) $options['debug'];
+        $this->charset            = $options['charset'];
+        $this->baseTemplateClass  = $options['base_template_class'];
+        $this->autoReload         = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
+        $this->extensions         = array(
+            'core'      => new Twig_Extension_Core(),
+            'escaper'   => new Twig_Extension_Escaper((bool) $options['autoescape']),
+            'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),
+        );
+        $this->strictVariables    = (bool) $options['strict_variables'];
+        $this->runtimeInitialized = false;
+        $this->setCache($options['cache']);
+        $this->functionCallbacks = array();
+        $this->filterCallbacks = array();
+    }
+
+    /**
+     * Gets the base template class for compiled templates.
+     *
+     * @return string The base template class name
+     */
+    public function getBaseTemplateClass()
+    {
+        return $this->baseTemplateClass;
+    }
+
+    /**
+     * Sets the base template class for compiled templates.
+     *
+     * @param string $class The base template class name
+     */
+    public function setBaseTemplateClass($class)
+    {
+        $this->baseTemplateClass = $class;
+    }
+
+    /**
+     * Enables debugging mode.
+     */
+    public function enableDebug()
+    {
+        $this->debug = true;
+    }
+
+    /**
+     * Disables debugging mode.
+     */
+    public function disableDebug()
+    {
+        $this->debug = false;
+    }
+
+    /**
+     * Checks if debug mode is enabled.
+     *
+     * @return Boolean true if debug mode is enabled, false otherwise
+     */
+    public function isDebug()
+    {
+        return $this->debug;
+    }
+
+    /**
+     * Enables the auto_reload option.
+     */
+    public function enableAutoReload()
+    {
+        $this->autoReload = true;
+    }
+
+    /**
+     * Disables the auto_reload option.
+     */
+    public function disableAutoReload()
+    {
+        $this->autoReload = false;
+    }
+
+    /**
+     * Checks if the auto_reload option is enabled.
+     *
+     * @return Boolean true if auto_reload is enabled, false otherwise
+     */
+    public function isAutoReload()
+    {
+        return $this->autoReload;
+    }
+
+    /**
+     * Enables the strict_variables option.
+     */
+    public function enableStrictVariables()
+    {
+        $this->strictVariables = true;
+    }
+
+    /**
+     * Disables the strict_variables option.
+     */
+    public function disableStrictVariables()
+    {
+        $this->strictVariables = false;
+    }
+
+    /**
+     * Checks if the strict_variables option is enabled.
+     *
+     * @return Boolean true if strict_variables is enabled, false otherwise
+     */
+    public function isStrictVariables()
+    {
+        return $this->strictVariables;
+    }
+
+    /**
+     * Gets the cache directory or false if cache is disabled.
+     *
+     * @return string|false
+     */
+    public function getCache()
+    {
+        return $this->cache;
+    }
+
+     /**
+      * Sets the cache directory or false if cache is disabled.
+      *
+      * @param string|false $cache The absolute path to the compiled templates,
+      *                            or false to disable cache
+      */
+    public function setCache($cache)
+    {
+        $this->cache = $cache ? $cache : false;
+    }
+
+    /**
+     * Gets the cache filename for a given template.
+     *
+     * @param string $name The template name
+     *
+     * @return string The cache file name
+     */
+    public function getCacheFilename($name)
+    {
+        if (false === $this->cache) {
+            return false;
+        }
+
+        $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
+
+        return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
+    }
+
+    /**
+     * Gets the template class associated with the given string.
+     *
+     * @param string $name The name for which to calculate the template class name
+     *
+     * @return string The template class name
+     */
+    public function getTemplateClass($name)
+    {
+        return $this->templateClassPrefix.md5($this->loader->getCacheKey($name));
+    }
+
+    /**
+     * Gets the template class prefix.
+     *
+     * @return string The template class prefix
+     */
+    public function getTemplateClassPrefix()
+    {
+        return $this->templateClassPrefix;
+    }
+
+    /**
+     * Renders a template.
+     *
+     * @param string $name    The template name
+     * @param array  $context An array of parameters to pass to the template
+     *
+     * @return string The rendered template
+     */
+    public function render($name, array $context = array())
+    {
+        return $this->loadTemplate($name)->render($context);
+    }
+
+    /**
+     * Loads a template by name.
+     *
+     * @param  string  $name  The template name
+     *
+     * @return Twig_TemplateInterface A template instance representing the given template name
+     */
+    public function loadTemplate($name)
+    {
+        $cls = $this->getTemplateClass($name);
+
+        if (isset($this->loadedTemplates[$cls])) {
+            return $this->loadedTemplates[$cls];
+        }
+
+        if (!class_exists($cls, false)) {
+            if (false === $cache = $this->getCacheFilename($name)) {
+                eval('?>'.$this->compileSource($this->loader->getSource($name), $name));
+            } else {
+                if (!file_exists($cache) || ($this->isAutoReload() && !$this->loader->isFresh($name, filemtime($cache)))) {
+                    $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name));
+                }
+
+                require_once $cache;
+            }
+        }
+
+        if (!$this->runtimeInitialized) {
+            $this->initRuntime();
+        }
+
+        return $this->loadedTemplates[$cls] = new $cls($this);
+    }
+
+    /**
+     * Clears the internal template cache.
+     */
+    public function clearTemplateCache()
+    {
+        $this->loadedTemplates = array();
+    }
+
+    /**
+     * Clears the template cache files on the filesystem.
+     */
+    public function clearCacheFiles()
+    {
+        if (false === $this->cache) {
+            return;
+        }
+
+        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
+            if ($file->isFile()) {
+                @unlink($file->getPathname());
+            }
+        }
+    }
+
+    /**
+     * Gets the Lexer instance.
+     *
+     * @return Twig_LexerInterface A Twig_LexerInterface instance
+     */
+    public function getLexer()
+    {
+        if (null === $this->lexer) {
+            $this->lexer = new Twig_Lexer($this);
+        }
+
+        return $this->lexer;
+    }
+
+    /**
+     * Sets the Lexer instance.
+     *
+     * @param Twig_LexerInterface A Twig_LexerInterface instance
+     */
+    public function setLexer(Twig_LexerInterface $lexer)
+    {
+        $this->lexer = $lexer;
+    }
+
+    /**
+     * Tokenizes a source code.
+     *
+     * @param string $source The template source code
+     * @param string $name   The template name
+     *
+     * @return Twig_TokenStream A Twig_TokenStream instance
+     */
+    public function tokenize($source, $name = null)
+    {
+        return $this->getLexer()->tokenize($source, $name);
+    }
+
+    /**
+     * Gets the Parser instance.
+     *
+     * @return Twig_ParserInterface A Twig_ParserInterface instance
+     */
+    public function getParser()
+    {
+        if (null === $this->parser) {
+            $this->parser = new Twig_Parser($this);
+        }
+
+        return $this->parser;
+    }
+
+    /**
+     * Sets the Parser instance.
+     *
+     * @param Twig_ParserInterface A Twig_ParserInterface instance
+     */
+    public function setParser(Twig_ParserInterface $parser)
+    {
+        $this->parser = $parser;
+    }
+
+    /**
+     * Parses a token stream.
+     *
+     * @param Twig_TokenStream $tokens A Twig_TokenStream instance
+     *
+     * @return Twig_Node_Module A Node tree
+     */
+    public function parse(Twig_TokenStream $tokens)
+    {
+        return $this->getParser()->parse($tokens);
+    }
+
+    /**
+     * Gets the Compiler instance.
+     *
+     * @return Twig_CompilerInterface A Twig_CompilerInterface instance
+     */
+    public function getCompiler()
+    {
+        if (null === $this->compiler) {
+            $this->compiler = new Twig_Compiler($this);
+        }
+
+        return $this->compiler;
+    }
+
+    /**
+     * Sets the Compiler instance.
+     *
+     * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance
+     */
+    public function setCompiler(Twig_CompilerInterface $compiler)
+    {
+        $this->compiler = $compiler;
+    }
+
+    /**
+     * Compiles a Node.
+     *
+     * @param Twig_NodeInterface $node A Twig_NodeInterface instance
+     *
+     * @return string The compiled PHP source code
+     */
+    public function compile(Twig_NodeInterface $node)
+    {
+        return $this->getCompiler()->compile($node)->getSource();
+    }
+
+    /**
+     * Compiles a template source code.
+     *
+     * @param string $source The template source code
+     * @param string $name   The template name
+     *
+     * @return string The compiled PHP source code
+     */
+    public function compileSource($source, $name = null)
+    {
+        return $this->compile($this->parse($this->tokenize($source, $name)));
+    }
+
+    /**
+     * Sets the Loader instance.
+     *
+     * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance
+     */
+    public function setLoader(Twig_LoaderInterface $loader)
+    {
+        $this->loader = $loader;
+    }
+
+    /**
+     * Gets the Loader instance.
+     *
+     * @return Twig_LoaderInterface A Twig_LoaderInterface instance
+     */
+    public function getLoader()
+    {
+        return $this->loader;
+    }
+
+    /**
+     * Sets the default template charset.
+     *
+     * @param string $charset The default charset
+     */
+    public function setCharset($charset)
+    {
+        $this->charset = $charset;
+    }
+
+    /**
+     * Gets the default template charset.
+     *
+     * @return string The default charset
+     */
+    public function getCharset()
+    {
+        return $this->charset;
+    }
+
+    /**
+     * Initializes the runtime environment.
+     */
+    public function initRuntime()
+    {
+        $this->runtimeInitialized = true;
+
+        foreach ($this->getExtensions() as $extension) {
+            $extension->initRuntime($this);
+        }
+    }
+
+    /**
+     * Returns true if the given extension is registered.
+     *
+     * @param string $name The extension name
+     *
+     * @return Boolean Whether the extension is registered or not
+     */
+    public function hasExtension($name)
+    {
+        return isset($this->extensions[$name]);
+    }
+
+    /**
+     * Gets an extension by name.
+     *
+     * @param string $name The extension name
+     *
+     * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
+     */
+    public function getExtension($name)
+    {
+        if (!isset($this->extensions[$name])) {
+            throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
+        }
+
+        return $this->extensions[$name];
+    }
+
+    /**
+     * Registers an extension.
+     *
+     * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance
+     */
+    public function addExtension(Twig_ExtensionInterface $extension)
+    {
+        $this->extensions[$extension->getName()] = $extension;
+    }
+
+    /**
+     * Removes an extension by name.
+     *
+     * @param string $name The extension name
+     */
+    public function removeExtension($name)
+    {
+        unset($this->extensions[$name]);
+    }
+
+    /**
+     * Registers an array of extensions.
+     *
+     * @param array $extensions An array of extensions
+     */
+    public function setExtensions(array $extensions)
+    {
+        foreach ($extensions as $extension) {
+            $this->addExtension($extension);
+        }
+    }
+
+    /**
+     * Returns all registered extensions.
+     *
+     * @return array An array of extensions
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Registers a Token Parser.
+     *
+     * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
+     */
+    public function addTokenParser(Twig_TokenParserInterface $parser)
+    {
+        if (null === $this->parsers) {
+            $this->getTokenParsers();
+        }
+
+        $this->parsers->addTokenParser($parser);
+    }
+
+    /**
+     * Gets the registered Token Parsers.
+     *
+     * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
+     */
+    public function getTokenParsers()
+    {
+        if (null === $this->parsers) {
+            $this->parsers = new Twig_TokenParserBroker;
+            foreach ($this->getExtensions() as $extension) {
+                $parsers = $extension->getTokenParsers();
+                foreach($parsers as $parser) {
+                    if ($parser instanceof Twig_TokenParserInterface) {
+                        $this->parsers->addTokenParser($parser);
+                    } else if ($parser instanceof Twig_TokenParserBrokerInterface) {
+                        $this->parsers->addTokenParserBroker($parser);
+                    } else {
+                        throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
+                    }
+                }
+            }
+        }
+
+        return $this->parsers;
+    }
+
+    /**
+     * Registers a Node Visitor.
+     *
+     * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance
+     */
+    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
+    {
+        if (null === $this->visitors) {
+            $this->getNodeVisitors();
+        }
+
+        $this->visitors[] = $visitor;
+    }
+
+    /**
+     * Gets the registered Node Visitors.
+     *
+     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
+     */
+    public function getNodeVisitors()
+    {
+        if (null === $this->visitors) {
+            $this->visitors = array();
+            foreach ($this->getExtensions() as $extension) {
+                $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
+            }
+        }
+
+        return $this->visitors;
+    }
+
+    /**
+     * Registers a Filter.
+     *
+     * @param string               $name    The filter name
+     * @param Twig_FilterInterface $visitor A Twig_FilterInterface instance
+     */
+    public function addFilter($name, Twig_FilterInterface $filter)
+    {
+        if (null === $this->filters) {
+            $this->loadFilters();
+        }
+
+        $this->filters[$name] = $filter;
+    }
+
+    /**
+     * Get a filter by name.
+     *
+     * Subclasses may override this method and load filters differently;
+     * so no list of filters is available.
+     *
+     * @param string $name The filter name
+     *
+     * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists
+     */
+    public function getFilter($name)
+    {
+        if (null === $this->filters) {
+            $this->loadFilters();
+        }
+
+        if (isset($this->filters[$name])) {
+            return $this->filters[$name];
+        }
+
+        foreach ($this->filterCallbacks as $callback) {
+            if (false !== $filter = call_user_func($callback, $name)) {
+                return $filter;
+            }
+        }
+
+        return false;
+    }
+
+    public function registerUndefinedFilterCallback($callable)
+    {
+        $this->filterCallbacks[] = $callable;
+    }
+
+    /**
+     * Gets the registered Filters.
+     *
+     * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
+     */
+    protected function loadFilters()
+    {
+        $this->filters = array();
+        foreach ($this->getExtensions() as $extension) {
+            $this->filters = array_merge($this->filters, $extension->getFilters());
+        }
+    }
+
+    /**
+     * Registers a Test.
+     *
+     * @param string             $name    The test name
+     * @param Twig_TestInterface $visitor A Twig_TestInterface instance
+     */
+    public function addTest($name, Twig_TestInterface $test)
+    {
+        if (null === $this->tests) {
+            $this->getTests();
+        }
+
+        $this->tests[$name] = $test;
+    }
+
+    /**
+     * Gets the registered Tests.
+     *
+     * @return Twig_TestInterface[] An array of Twig_TestInterface instances
+     */
+    public function getTests()
+    {
+        if (null === $this->tests) {
+            $this->tests = array();
+            foreach ($this->getExtensions() as $extension) {
+                $this->tests = array_merge($this->tests, $extension->getTests());
+            }
+        }
+
+        return $this->tests;
+    }
+
+    /**
+     * Registers a Function.
+     *
+     * @param string                 $name     The function name
+     * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance
+     */
+    public function addFunction($name, Twig_FunctionInterface $function)
+    {
+        if (null === $this->functions) {
+            $this->loadFunctions();
+        }
+
+        $this->functions[$name] = $function;
+    }
+
+    /**
+     * Get a function by name.
+     *
+     * Subclasses may override this method and load functions differently;
+     * so no list of functions is available.
+     *
+     * @param string $name function name
+     *
+     * @return Twig_Function|false A Twig_Function instance or false if the function does not exists
+     */
+    public function getFunction($name)
+    {
+        if (null === $this->functions) {
+            $this->loadFunctions();
+        }
+
+        if (isset($this->functions[$name])) {
+            return $this->functions[$name];
+        }
+
+        foreach ($this->functionCallbacks as $callback) {
+            if (false !== $function = call_user_func($callback, $name)) {
+                return $function;
+            }
+        }
+
+        return false;
+    }
+
+    public function registerUndefinedFunctionCallback($callable)
+    {
+        $this->functionCallbacks[] = $callable;
+    }
+
+    protected function loadFunctions() {
+        $this->functions = array();
+        foreach ($this->getExtensions() as $extension) {
+            $this->functions = array_merge($this->functions, $extension->getFunctions());
+        }
+    }
+
+    /**
+     * Registers a Global.
+     *
+     * @param string $name  The global name
+     * @param mixed  $value The global value
+     */
+    public function addGlobal($name, $value)
+    {
+        if (null === $this->globals) {
+            $this->getGlobals();
+        }
+
+        $this->globals[$name] = $value;
+    }
+
+    /**
+     * Gets the registered Globals.
+     *
+     * @return array An array of globals
+     */
+    public function getGlobals()
+    {
+        if (null === $this->globals) {
+            $this->globals = array();
+            foreach ($this->getExtensions() as $extension) {
+                $this->globals = array_merge($this->globals, $extension->getGlobals());
+            }
+        }
+
+        return $this->globals;
+    }
+
+    /**
+     * Gets the registered unary Operators.
+     *
+     * @return array An array of unary operators
+     */
+    public function getUnaryOperators()
+    {
+        if (null === $this->unaryOperators) {
+            $this->initOperators();
+        }
+
+        return $this->unaryOperators;
+    }
+
+    /**
+     * Gets the registered binary Operators.
+     *
+     * @return array An array of binary operators
+     */
+    public function getBinaryOperators()
+    {
+        if (null === $this->binaryOperators) {
+            $this->initOperators();
+        }
+
+        return $this->binaryOperators;
+    }
+
+    protected function initOperators()
+    {
+        $this->unaryOperators = array();
+        $this->binaryOperators = array();
+        foreach ($this->getExtensions() as $extension) {
+            $operators = $extension->getOperators();
+
+            if (!$operators) {
+                continue;
+            }
+
+            if (2 !== count($operators)) {
+                throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
+            }
+
+            $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
+            $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
+        }
+    }
+
+    protected function writeCacheFile($file, $content)
+    {
+        if (!is_dir(dirname($file))) {
+            mkdir(dirname($file), 0777, true);
+        }
+
+        $tmpFile = tempnam(dirname($file), basename($file));
+        if (false !== @file_put_contents($tmpFile, $content)) {
+            // rename does not work on Win32 before 5.2.6
+            if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
+                chmod($file, 0644);
+
+                return;
+            }
+        }
+
+        throw new Twig_Error_Runtime(sprintf('Failed to write cache file "%s".', $file));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Error.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Error.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Error.php	(revision 345)
@@ -0,0 +1,184 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig base exception.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Error extends Exception
+{
+    protected $lineno;
+    protected $filename;
+    protected $rawMessage;
+    protected $previous;
+
+    /**
+     * Constructor.
+     *
+     * @param string    $message  The error message
+     * @param integer   $lineno   The template line where the error occurred
+     * @param string    $filename The template file name where the error occurred
+     * @param Exception $previous The previous exception
+     */
+    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
+    {
+        if (-1 === $lineno || null === $filename) {
+            list($lineno, $filename) = $this->findTemplateInfo(null !== $previous ? $previous : $this);
+        }
+
+        $this->lineno = $lineno;
+        $this->filename = $filename;
+        $this->rawMessage = $message;
+
+        $this->updateRepr();
+
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->previous = $previous;
+            parent::__construct($this->message);
+        } else {
+            parent::__construct($this->message, 0, $previous);
+        }
+    }
+
+    /**
+     * Gets the filename where the error occurred.
+     *
+     * @return string The filename
+     */
+    public function getTemplateFile()
+    {
+        return $this->filename;
+    }
+
+    /**
+     * Sets the filename where the error occurred.
+     *
+     * @param string $filename The filename
+     */
+    public function setTemplateFile($filename)
+    {
+        $this->filename = $filename;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * Gets the template line where the error occurred.
+     *
+     * @return integer The template line
+     */
+    public function getTemplateLine()
+    {
+        return $this->lineno;
+    }
+
+    /**
+     * Sets the template line where the error occurred.
+     *
+     * @param integer $lineno The template line
+     */
+    public function setTemplateLine($lineno)
+    {
+        $this->lineno = $lineno;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * For PHP < 5.3.0, provides access to the getPrevious() method.
+     *
+     * @param  string $method    The method name
+     * @param  array  $arguments The parameters to be passed to the method
+     *
+     * @return Exception The previous exception or null
+     */
+    public function __call($method, $arguments)
+    {
+        if ('getprevious' == strtolower($method)) {
+            return $this->previous;
+        }
+
+        throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
+    }
+
+    protected function updateRepr()
+    {
+        $this->message = $this->rawMessage;
+
+        $dot = false;
+        if ('.' === substr($this->message, -1)) {
+            $this->message = substr($this->message, 0, -1);
+            $dot = true;
+        }
+
+        if (null !== $this->filename) {
+            $this->message .= sprintf(' in %s', json_encode($this->filename));
+        }
+
+        if ($this->lineno >= 0) {
+            $this->message .= sprintf(' at line %d', $this->lineno);
+        }
+
+        if ($dot) {
+            $this->message .= '.';
+        }
+    }
+
+    protected function findTemplateInfo(Exception $e)
+    {
+        if (!function_exists('token_get_all')) {
+            return array(-1, null);
+        }
+
+        $traces = $e->getTrace();
+        foreach ($traces as $i => $trace) {
+            if (!isset($trace['class']) || 'Twig_Template' === $trace['class']) {
+                continue;
+            }
+
+            $r = new ReflectionClass($trace['class']);
+            if (!$r->implementsInterface('Twig_TemplateInterface')) {
+                continue;
+            }
+
+            if (!file_exists($r->getFilename())) {
+                // probably an eval()'d code
+                return array(-1, null);
+            }
+
+            $trace = $traces[$i - 1];
+            if (!isset($trace['line'])) {
+                $trace['line'] = -log(0);
+            }
+
+            $tokens = token_get_all(file_get_contents($r->getFilename()));
+            $templateline = -1;
+            $template = null;
+            while ($token = array_shift($tokens)) {
+                if (isset($token[2]) && $token[2] >= $trace['line']) {
+                    return array($templateline, $template);
+                }
+
+                if (T_COMMENT === $token[0] && null === $template && preg_match('#/\* +(.+) +\*/#', $token[1], $match)) {
+                    $template = $match[1];
+                } elseif (T_COMMENT === $token[0] && preg_match('#^//\s*line (\d+)\s*$#', $token[1], $match)) {
+                    $templateline = $match[1];
+                }
+            }
+
+            return array(-1, $template);
+        }
+
+        return array(-1, null);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Loader.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Loader.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Loader.php	(revision 345)
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when an error occurs during template loading.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Error_Loader extends Twig_Error
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Runtime.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Runtime.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Runtime.php	(revision 345)
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when an error occurs at runtime.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Error_Runtime extends Twig_Error
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Syntax.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Syntax.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Error/Syntax.php	(revision 345)
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when a syntax error occurs during lexing or parsing of a template.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Error_Syntax extends Twig_Error
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/ExpressionParser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/ExpressionParser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/ExpressionParser.php	(revision 345)
@@ -0,0 +1,379 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Parses expressions.
+ *
+ * This parser implements a "Precedence climbing" algorithm.
+ *
+ * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
+ * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_ExpressionParser
+{
+    const OPERATOR_LEFT = 1;
+    const OPERATOR_RIGHT = 2;
+
+    protected $parser;
+    protected $unaryOperators;
+    protected $binaryOperators;
+
+    public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
+    {
+        $this->parser = $parser;
+        $this->unaryOperators = $unaryOperators;
+        $this->binaryOperators = $binaryOperators;
+    }
+
+    public function parseExpression($precedence = 0)
+    {
+        $expr = $this->getPrimary();
+        $token = $this->parser->getCurrentToken();
+        while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
+            $op = $this->binaryOperators[$token->getValue()];
+            $this->parser->getStream()->next();
+
+            if (isset($op['callable'])) {
+                $expr = call_user_func($op['callable'], $this->parser, $expr);
+            } else {
+                $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
+                $class = $op['class'];
+                $expr = new $class($expr, $expr1, $token->getLine());
+            }
+
+            $token = $this->parser->getCurrentToken();
+        }
+
+        if (0 === $precedence) {
+            return $this->parseConditionalExpression($expr);
+        }
+
+        return $expr;
+    }
+
+    protected function getPrimary()
+    {
+        $token = $this->parser->getCurrentToken();
+
+        if ($this->isUnary($token)) {
+            $operator = $this->unaryOperators[$token->getValue()];
+            $this->parser->getStream()->next();
+            $expr = $this->parseExpression($operator['precedence']);
+            $class = $operator['class'];
+
+            return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
+        } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
+            $this->parser->getStream()->next();
+            $expr = $this->parseExpression();
+            $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
+
+            return $this->parsePostfixExpression($expr);
+        }
+
+        return $this->parsePrimaryExpression();
+    }
+
+    protected function parseConditionalExpression($expr)
+    {
+        while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) {
+            $this->parser->getStream()->next();
+            $expr2 = $this->parseExpression();
+            $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value');
+            $expr3 = $this->parseExpression();
+
+            $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
+        }
+
+        return $expr;
+    }
+
+    protected function isUnary(Twig_Token $token)
+    {
+        return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
+    }
+
+    protected function isBinary(Twig_Token $token)
+    {
+        return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
+    }
+
+    public function parsePrimaryExpression()
+    {
+        $token = $this->parser->getCurrentToken();
+        switch ($token->getType()) {
+            case Twig_Token::NAME_TYPE:
+                $this->parser->getStream()->next();
+                switch ($token->getValue()) {
+                    case 'true':
+                    case 'TRUE':
+                        $node = new Twig_Node_Expression_Constant(true, $token->getLine());
+                        break;
+
+                    case 'false':
+                    case 'FALSE':
+                        $node = new Twig_Node_Expression_Constant(false, $token->getLine());
+                        break;
+
+                    case 'none':
+                    case 'NONE':
+                    case 'null':
+                    case 'NULL':
+                        $node = new Twig_Node_Expression_Constant(null, $token->getLine());
+                        break;
+
+                    default:
+                        $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
+                }
+                break;
+
+            case Twig_Token::NUMBER_TYPE:
+            case Twig_Token::STRING_TYPE:
+                $this->parser->getStream()->next();
+                $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
+                break;
+
+            default:
+                if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
+                    $node = $this->parseArrayExpression();
+                } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
+                    $node = $this->parseHashExpression();
+                } else {
+                    throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine());
+                }
+        }
+
+        return $this->parsePostfixExpression($node);
+    }
+
+    public function parseArrayExpression()
+    {
+        $stream = $this->parser->getStream();
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
+        $elements = array();
+        while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
+            if (!empty($elements)) {
+                $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
+
+                // trailing ,?
+                if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
+                    break;
+                }
+            }
+
+            $elements[] = $this->parseExpression();
+        }
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
+
+        return new Twig_Node_Expression_Array($elements, $stream->getCurrent()->getLine());
+    }
+
+    public function parseHashExpression()
+    {
+        $stream = $this->parser->getStream();
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
+        $elements = array();
+        while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
+            if (!empty($elements)) {
+                $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
+
+                // trailing ,?
+                if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
+                    break;
+                }
+            }
+
+            if (!$stream->test(Twig_Token::STRING_TYPE) && !$stream->test(Twig_Token::NUMBER_TYPE)) {
+                $current = $stream->getCurrent();
+                throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string or a number (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine());
+            }
+
+            $key = $stream->next()->getValue();
+            $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
+            $elements[$key] = $this->parseExpression();
+        }
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
+
+        return new Twig_Node_Expression_Array($elements, $stream->getCurrent()->getLine());
+    }
+
+    public function parsePostfixExpression($node)
+    {
+        $firstPass = true;
+        while (true) {
+            $token = $this->parser->getCurrentToken();
+            if ($token->getType() == Twig_Token::PUNCTUATION_TYPE) {
+                if ('.' == $token->getValue() || '[' == $token->getValue()) {
+                    $node = $this->parseSubscriptExpression($node);
+                } elseif ('|' == $token->getValue()) {
+                    $node = $this->parseFilterExpression($node);
+                } elseif ($firstPass && $node instanceof Twig_Node_Expression_Name && '(' == $token->getValue()) {
+                    $node = $this->getFunctionNode($node);
+                } else {
+                    break;
+                }
+            } else {
+                break;
+            }
+
+            $firstPass = false;
+        }
+
+        return $node;
+    }
+
+    public function getFunctionNode(Twig_Node_Expression_Name $node)
+    {
+        $args = $this->parseArguments();
+
+        if ('parent' === $node->getAttribute('name')) {
+            if (!count($this->parser->getBlockStack())) {
+                throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $node->getLine());
+            }
+
+            if (!$this->parser->getParent()) {
+                throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend another one is forbidden', $node->getLine());
+            }
+
+            return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $node->getLine());
+        }
+
+        if ('block' === $node->getAttribute('name')) {
+            return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $node->getLine());
+        }
+
+        if (null !== $alias = $this->parser->getImportedFunction($node->getAttribute('name'))) {
+            return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $node->getLine()), $args, Twig_TemplateInterface::METHOD_CALL, $node->getLine());
+        }
+
+        return new Twig_Node_Expression_Function($node, $args, $node->getLine());
+    }
+
+    public function parseSubscriptExpression($node)
+    {
+        $token = $this->parser->getStream()->next();
+        $lineno = $token->getLine();
+        $arguments = new Twig_Node();
+        $type = Twig_TemplateInterface::ANY_CALL;
+        if ($token->getValue() == '.') {
+            $token = $this->parser->getStream()->next();
+            if (
+                $token->getType() == Twig_Token::NAME_TYPE
+                ||
+                $token->getType() == Twig_Token::NUMBER_TYPE
+                ||
+                ($token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue()))
+            ) {
+                $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
+
+                if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
+                    $type = Twig_TemplateInterface::METHOD_CALL;
+                    $arguments = $this->parseArguments();
+                } else {
+                    $arguments = new Twig_Node();
+                }
+            } else {
+                throw new Twig_Error_Syntax('Expected name or number', $lineno);
+            }
+        } else {
+            $type = Twig_TemplateInterface::ARRAY_CALL;
+
+            $arg = $this->parseExpression();
+            $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ']');
+        }
+
+        return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
+    }
+
+    public function parseFilterExpression($node)
+    {
+        $this->parser->getStream()->next();
+
+        return $this->parseFilterExpressionRaw($node);
+    }
+
+    public function parseFilterExpressionRaw($node, $tag = null)
+    {
+        while (true) {
+            $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
+
+            $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
+            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
+                $arguments = new Twig_Node();
+            } else {
+                $arguments = $this->parseArguments();
+            }
+
+            $node = new Twig_Node_Expression_Filter($node, $name, $arguments, $token->getLine(), $tag);
+
+            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
+                break;
+            }
+
+            $this->parser->getStream()->next();
+        }
+
+        return $node;
+    }
+
+    public function parseArguments()
+    {
+        $args = array();
+        $stream = $this->parser->getStream();
+
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis');
+        while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) {
+            if (!empty($args)) {
+                $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
+            }
+            $args[] = $this->parseExpression();
+        }
+        $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
+
+        return new Twig_Node($args);
+    }
+
+    public function parseAssignmentExpression()
+    {
+        $targets = array();
+        while (true) {
+            $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
+            if (in_array($token->getValue(), array('true', 'false', 'none'))) {
+                throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine());
+            }
+            $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine());
+
+            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+                break;
+            }
+            $this->parser->getStream()->next();
+        }
+
+        return new Twig_Node($targets);
+    }
+
+    public function parseMultitargetExpression()
+    {
+        $targets = array();
+        while (true) {
+            $targets[] = $this->parseExpression();
+            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+                break;
+            }
+            $this->parser->getStream()->next();
+        }
+
+        return new Twig_Node($targets);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Extension.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Extension.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Extension.php	(revision 345)
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class Twig_Extension implements Twig_ExtensionInterface
+{
+    /**
+     * Initializes the runtime environment.
+     *
+     * This is where you can load some file that contains filter functions for instance.
+     *
+     * @param Twig_Environment $environment The current Twig_Environment instance
+     */
+    public function initRuntime(Twig_Environment $environment)
+    {
+    }
+
+    /**
+     * Returns the token parser instances to add to the existing list.
+     *
+     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+     */
+    public function getTokenParsers()
+    {
+        return array();
+    }
+
+    /**
+     * Returns the node visitor instances to add to the existing list.
+     *
+     * @return array An array of Twig_NodeVisitorInterface instances
+     */
+    public function getNodeVisitors()
+    {
+        return array();
+    }
+
+    /**
+     * Returns a list of filters to add to the existing list.
+     *
+     * @return array An array of filters
+     */
+    public function getFilters()
+    {
+        return array();
+    }
+
+    /**
+     * Returns a list of tests to add to the existing list.
+     *
+     * @return array An array of tests
+     */
+    public function getTests()
+    {
+        return array();
+    }
+
+    /**
+     * Returns a list of functions to add to the existing list.
+     *
+     * @return array An array of functions
+     */
+    public function getFunctions()
+    {
+        return array();
+    }
+
+    /**
+     * Returns a list of operators to add to the existing list.
+     *
+     * @return array An array of operators
+     */
+    public function getOperators()
+    {
+        return array();
+    }
+
+    /**
+     * Returns a list of global functions to add to the existing list.
+     *
+     * @return array An array of global functions
+     */
+    public function getGlobals()
+    {
+        return array();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Core.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Core.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Core.php	(revision 345)
@@ -0,0 +1,499 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extension_Core extends Twig_Extension
+{
+    /**
+     * Returns the token parser instance to add to the existing list.
+     *
+     * @return array An array of Twig_TokenParser instances
+     */
+    public function getTokenParsers()
+    {
+        return array(
+            new Twig_TokenParser_For(),
+            new Twig_TokenParser_If(),
+            new Twig_TokenParser_Extends(),
+            new Twig_TokenParser_Include(),
+            new Twig_TokenParser_Block(),
+            new Twig_TokenParser_Filter(),
+            new Twig_TokenParser_Macro(),
+            new Twig_TokenParser_Import(),
+            new Twig_TokenParser_From(),
+            new Twig_TokenParser_Set(),
+            new Twig_TokenParser_Spaceless(),
+        );
+    }
+
+    /**
+     * Returns a list of filters to add to the existing list.
+     *
+     * @return array An array of filters
+     */
+    public function getFilters()
+    {
+        $filters = array(
+            // formatting filters
+            'date'    => new Twig_Filter_Function('twig_date_format_filter'),
+            'format'  => new Twig_Filter_Function('sprintf'),
+            'replace' => new Twig_Filter_Function('twig_strtr'),
+
+            // encoding
+            'url_encode'  => new Twig_Filter_Function('twig_urlencode_filter'),
+            'json_encode' => new Twig_Filter_Function('json_encode'),
+
+            // string filters
+            'title'      => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)),
+            'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)),
+            'upper'      => new Twig_Filter_Function('strtoupper'),
+            'lower'      => new Twig_Filter_Function('strtolower'),
+            'striptags'  => new Twig_Filter_Function('strip_tags'),
+
+            // array helpers
+            'join'    => new Twig_Filter_Function('twig_join_filter'),
+            'reverse' => new Twig_Filter_Function('twig_reverse_filter'),
+            'length'  => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)),
+            'sort'    => new Twig_Filter_Function('twig_sort_filter'),
+            'merge'   => new Twig_Filter_Function('twig_array_merge'),
+
+            // iteration and runtime
+            'default' => new Twig_Filter_Function('twig_default_filter'),
+            'keys'    => new Twig_Filter_Function('twig_get_array_keys_filter'),
+
+            // escaping
+            'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')),
+            'e'      => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')),
+        );
+
+        if (function_exists('mb_get_info')) {
+            $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true));
+            $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true));
+        }
+
+        return $filters;
+    }
+
+    /**
+     * Returns a list of global functions to add to the existing list.
+     *
+     * @return array An array of global functions
+     */
+    public function getFunctions()
+    {
+        return array(
+            'range'    => new Twig_Function_Method($this, 'getRange'),
+            'constant' => new Twig_Function_Method($this, 'getConstant'),
+            'cycle'    => new Twig_Function_Method($this, 'getCycle'),
+        );
+    }
+
+    public function getRange($start, $end, $step = 1)
+    {
+        return range($start, $end, $step);
+    }
+
+    public function getConstant($value)
+    {
+        return constant($value);
+    }
+
+    public function getCycle($values, $i)
+    {
+        if (!is_array($values) && !$values instanceof ArrayAccess) {
+            return $values;
+        }
+
+        return $values[$i % count($values)];
+    }
+
+    /**
+     * Returns a list of filters to add to the existing list.
+     *
+     * @return array An array of filters
+     */
+    public function getTests()
+    {
+        return array(
+            'even'        => new Twig_Test_Function('twig_test_even'),
+            'odd'         => new Twig_Test_Function('twig_test_odd'),
+            'defined'     => new Twig_Test_Function('twig_test_defined'),
+            'sameas'      => new Twig_Test_Function('twig_test_sameas'),
+            'none'        => new Twig_Test_Function('twig_test_none'),
+            'divisibleby' => new Twig_Test_Function('twig_test_divisibleby'),
+            'constant'    => new Twig_Test_Function('twig_test_constant'),
+            'empty'       => new Twig_Test_Function('twig_test_empty'),
+        );
+    }
+
+    /**
+     * Returns a list of operators to add to the existing list.
+     *
+     * @return array An array of operators
+     */
+    public function getOperators()
+    {
+        return array(
+            array(
+                'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
+                '-'   => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'),
+                '+'   => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'),
+            ),
+            array(
+                'or'     => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'and'    => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '=='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '!='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '<'      => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '>'      => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '>='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '<='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'in'     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '+'      => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '-'      => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '~'      => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '*'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '/'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '//'     => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '%'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'is'     => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '..'     => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '**'     => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
+            ),
+        );
+    }
+
+    public function parseNotTestExpression(Twig_Parser $parser, $node)
+    {
+        return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
+    }
+
+    public function parseTestExpression(Twig_Parser $parser, $node)
+    {
+        $stream = $parser->getStream();
+        $name = $stream->expect(Twig_Token::NAME_TYPE);
+        $arguments = null;
+        if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
+            $arguments = $parser->getExpressionParser()->parseArguments();
+        }
+
+        return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $parser->getCurrentToken()->getLine());
+    }
+
+    /**
+     * Returns the name of the extension.
+     *
+     * @return string The extension name
+     */
+    public function getName()
+    {
+        return 'core';
+    }
+}
+
+function twig_date_format_filter($date, $format = 'F j, Y H:i')
+{
+    if (!$date instanceof DateTime) {
+        $date = new DateTime((ctype_digit($date) ? '@' : '').$date);
+    }
+
+    return $date->format($format);
+}
+
+function twig_urlencode_filter($url, $raw = false)
+{
+    if ($raw) {
+        return rawurlencode($url);
+    }
+
+    return urlencode($url);
+}
+
+function twig_array_merge($arr1, $arr2)
+{
+    if (!is_array($arr1) || !is_array($arr2)) {
+        throw new Twig_Error_Runtime('The merge filter only work with arrays or hashes.');
+    }
+
+    return array_merge($arr1, $arr2);
+}
+
+function twig_join_filter($value, $glue = '')
+{
+    return implode($glue, (array) $value);
+}
+
+function twig_default_filter($value, $default = '')
+{
+    return twig_test_empty($value) ? $default : $value;
+}
+
+function twig_get_array_keys_filter($array)
+{
+    if (is_object($array) && $array instanceof Traversable) {
+        return array_keys(iterator_to_array($array));
+    }
+
+    if (!is_array($array)) {
+        return array();
+    }
+
+    return array_keys($array);
+}
+
+function twig_reverse_filter($array)
+{
+    if (is_object($array) && $array instanceof Traversable) {
+        return array_reverse(iterator_to_array($array));
+    }
+
+    if (!is_array($array)) {
+        return array();
+    }
+
+    return array_reverse($array);
+}
+
+function twig_sort_filter($array)
+{
+    asort($array);
+
+    return $array;
+}
+
+function twig_in_filter($value, $compare)
+{
+    if (is_array($compare)) {
+        return in_array($value, $compare);
+    } elseif (is_string($compare)) {
+        return false !== strpos($compare, (string) $value);
+    } elseif (is_object($compare) && $compare instanceof Traversable) {
+        return in_array($value, iterator_to_array($compare, false));
+    }
+
+    return false;
+}
+
+function twig_strtr($pattern, $replacements)
+{
+    return str_replace(array_keys($replacements), array_values($replacements), $pattern);
+}
+
+/*
+ * Each type specifies a way for applying a transformation to a string
+ * The purpose is for the string to be "escaped" so it is suitable for
+ * the format it is being displayed in.
+ *
+ * For example, the string: "It's required that you enter a username & password.\n"
+ * If this were to be displayed as HTML it would be sensible to turn the
+ * ampersand into '&amp;' and the apostrophe into '&aps;'. However if it were
+ * going to be used as a string in JavaScript to be displayed in an alert box
+ * it would be right to leave the string as-is, but c-escape the apostrophe and
+ * the new line.
+ */
+function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $charset = null)
+{
+    if (is_object($string) && $string instanceof Twig_Markup) {
+        return $string;
+    }
+
+    if (!is_string($string) && !(is_object($string) && method_exists($string, '__toString'))) {
+        return $string;
+    }
+
+    if (null === $charset) {
+        $charset = $env->getCharset();
+    }
+
+    switch ($type) {
+        case 'js':
+            // escape all non-alphanumeric characters
+            // into their \xHH or \uHHHH representations
+            if ('UTF-8' != $charset) {
+                $string = _twig_convert_encoding($string, 'UTF-8', $charset);
+            }
+
+            if (null === $string = preg_replace_callback('#[^\p{L}\p{N} ]#u', '_twig_escape_js_callback', $string)) {
+                throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
+            }
+
+            if ('UTF-8' != $charset) {
+                $string = _twig_convert_encoding($string, $charset, 'UTF-8');
+            }
+
+            return $string;
+
+        case 'html':
+            return htmlspecialchars($string, ENT_QUOTES, $charset);
+
+        default:
+            throw new Twig_Error_Runtime(sprintf('Invalid escape type "%s".', $type));
+    }
+}
+
+function twig_escape_filter_is_safe(Twig_Node $filterArgs)
+{
+    foreach ($filterArgs as $arg) {
+        if ($arg instanceof Twig_Node_Expression_Constant) {
+            return array($arg->getAttribute('value'));
+        } else {
+            return array();
+        }
+
+        break;
+    }
+
+    return array('html');
+}
+
+if (function_exists('iconv')) {
+    function _twig_convert_encoding($string, $to, $from)
+    {
+        return iconv($from, $to, $string);
+    }
+} elseif (function_exists('mb_convert_encoding')) {
+    function _twig_convert_encoding($string, $to, $from)
+    {
+        return mb_convert_encoding($string, $to, $from);
+    }
+} else {
+    function _twig_convert_encoding($string, $to, $from)
+    {
+        throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
+    }
+}
+
+function _twig_escape_js_callback($matches)
+{
+    $char = $matches[0];
+
+    // \xHH
+    if (!isset($char[1])) {
+        return '\\x'.substr('00'.bin2hex($char), -2);
+    }
+
+    // \uHHHH
+    $char = _twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
+
+    return '\\u'.substr('0000'.bin2hex($char), -4);
+}
+
+// add multibyte extensions if possible
+if (function_exists('mb_get_info')) {
+    function twig_length_filter(Twig_Environment $env, $thing)
+    {
+        return is_scalar($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing);
+    }
+
+    function twig_upper_filter(Twig_Environment $env, $string)
+    {
+        if (null !== ($charset = $env->getCharset())) {
+            return mb_strtoupper($string, $charset);
+        }
+
+        return strtoupper($string);
+    }
+
+    function twig_lower_filter(Twig_Environment $env, $string)
+    {
+        if (null !== ($charset = $env->getCharset())) {
+            return mb_strtolower($string, $charset);
+        }
+
+        return strtolower($string);
+    }
+
+    function twig_title_string_filter(Twig_Environment $env, $string)
+    {
+        if (null !== ($charset = $env->getCharset())) {
+            return mb_convert_case($string, MB_CASE_TITLE, $charset);
+        }
+
+        return ucwords(strtolower($string));
+    }
+
+    function twig_capitalize_string_filter(Twig_Environment $env, $string)
+    {
+        if (null !== ($charset = $env->getCharset())) {
+            return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).
+                         mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
+        }
+
+        return ucfirst(strtolower($string));
+    }
+}
+// and byte fallback
+else
+{
+    function twig_length_filter(Twig_Environment $env, $thing)
+    {
+        return is_scalar($thing) ? strlen($thing) : count($thing);
+    }
+
+    function twig_title_string_filter(Twig_Environment $env, $string)
+    {
+        return ucwords(strtolower($string));
+    }
+
+    function twig_capitalize_string_filter(Twig_Environment $env, $string)
+    {
+        return ucfirst(strtolower($string));
+    }
+}
+
+function twig_ensure_traversable($seq)
+{
+    if (is_array($seq) || (is_object($seq) && $seq instanceof Traversable)) {
+        return $seq;
+    } else {
+        return array();
+    }
+}
+
+function twig_test_sameas($value, $test)
+{
+    return $value === $test;
+}
+
+function twig_test_none($value)
+{
+    return null === $value;
+}
+
+function twig_test_divisibleby($value, $num)
+{
+    return 0 == $value % $num;
+}
+
+function twig_test_even($value)
+{
+    return $value % 2 == 0;
+}
+
+function twig_test_odd($value)
+{
+    return $value % 2 == 1;
+}
+
+function twig_test_constant($value, $constant)
+{
+    return constant($constant) === $value;
+}
+
+function twig_test_defined($name, $context)
+{
+    return array_key_exists($name, $context);
+}
+
+function twig_test_empty($value)
+{
+    return null === $value || false === $value || '' === (string) $value;
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Escaper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Escaper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Escaper.php	(revision 345)
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extension_Escaper extends Twig_Extension
+{
+    protected $autoescape;
+
+    public function __construct($autoescape = true)
+    {
+        $this->autoescape = $autoescape;
+    }
+
+    /**
+     * Returns the token parser instances to add to the existing list.
+     *
+     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+     */
+    public function getTokenParsers()
+    {
+        return array(new Twig_TokenParser_AutoEscape());
+    }
+
+    /**
+     * Returns the node visitor instances to add to the existing list.
+     *
+     * @return array An array of Twig_NodeVisitorInterface instances
+     */
+    public function getNodeVisitors()
+    {
+        return array(new Twig_NodeVisitor_Escaper());
+    }
+
+    /**
+     * Returns a list of filters to add to the existing list.
+     *
+     * @return array An array of filters
+     */
+    public function getFilters()
+    {
+        return array(
+            'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))),
+        );
+    }
+
+    public function isGlobal()
+    {
+        return $this->autoescape;
+    }
+
+    /**
+     * Returns the name of the extension.
+     *
+     * @return string The extension name
+     */
+    public function getName()
+    {
+        return 'escaper';
+    }
+}
+
+// tells the escaper node visitor that the string is safe
+function twig_raw_filter($string)
+{
+    return $string;
+}
+
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Optimizer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Optimizer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Optimizer.php	(revision 345)
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extension_Optimizer extends Twig_Extension
+{
+    protected $optimizers;
+
+    public function __construct($optimizers = -1)
+    {
+        $this->optimizers = $optimizers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getNodeVisitors()
+    {
+        return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'optimizer';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Sandbox.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Sandbox.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Extension/Sandbox.php	(revision 345)
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extension_Sandbox extends Twig_Extension
+{
+    protected $sandboxedGlobally;
+    protected $sandboxed;
+    protected $policy;
+
+    public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
+    {
+        $this->policy            = $policy;
+        $this->sandboxedGlobally = $sandboxed;
+    }
+
+    /**
+     * Returns the token parser instances to add to the existing list.
+     *
+     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+     */
+    public function getTokenParsers()
+    {
+        return array(new Twig_TokenParser_Sandbox());
+    }
+
+    /**
+     * Returns the node visitor instances to add to the existing list.
+     *
+     * @return array An array of Twig_NodeVisitorInterface instances
+     */
+    public function getNodeVisitors()
+    {
+        return array(new Twig_NodeVisitor_Sandbox());
+    }
+
+    public function enableSandbox()
+    {
+        $this->sandboxed = true;
+    }
+
+    public function disableSandbox()
+    {
+        $this->sandboxed = false;
+    }
+
+    public function isSandboxed()
+    {
+        return $this->sandboxedGlobally || $this->sandboxed;
+    }
+
+    public function isSandboxedGlobally()
+    {
+        return $this->sandboxedGlobally;
+    }
+
+    public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy)
+    {
+        $this->policy = $policy;
+    }
+
+    public function getSecurityPolicy()
+    {
+        return $this->policy;
+    }
+
+    public function checkSecurity($tags, $filters, $functions)
+    {
+        if ($this->isSandboxed()) {
+            $this->policy->checkSecurity($tags, $filters, $functions);
+        }
+    }
+
+    public function checkMethodAllowed($obj, $method)
+    {
+        if ($this->isSandboxed()) {
+            $this->policy->checkMethodAllowed($obj, $method);
+        }
+    }
+
+    public function checkPropertyAllowed($obj, $method)
+    {
+        if ($this->isSandboxed()) {
+            $this->policy->checkPropertyAllowed($obj, $method);
+        }
+    }
+
+    public function ensureToStringAllowed($obj)
+    {
+        if (is_object($obj)) {
+            $this->policy->checkMethodAllowed($obj, '__toString');
+        }
+
+        return $obj;
+    }
+
+    /**
+     * Returns the name of the extension.
+     *
+     * @return string The extension name
+     */
+    public function getName()
+    {
+        return 'sandbox';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/ExtensionInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/ExtensionInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/ExtensionInterface.php	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by extension classes.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_ExtensionInterface
+{
+    /**
+     * Initializes the runtime environment.
+     *
+     * This is where you can load some file that contains filter functions for instance.
+     *
+     * @param Twig_Environment $environment The current Twig_Environment instance
+     */
+    function initRuntime(Twig_Environment $environment);
+
+    /**
+     * Returns the token parser instances to add to the existing list.
+     *
+     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+     */
+    function getTokenParsers();
+
+    /**
+     * Returns the node visitor instances to add to the existing list.
+     *
+     * @return array An array of Twig_NodeVisitorInterface instances
+     */
+    function getNodeVisitors();
+
+    /**
+     * Returns a list of filters to add to the existing list.
+     *
+     * @return array An array of filters
+     */
+    function getFilters();
+
+    /**
+     * Returns a list of tests to add to the existing list.
+     *
+     * @return array An array of tests
+     */
+    function getTests();
+
+    /**
+     * Returns a list of functions to add to the existing list.
+     *
+     * @return array An array of functions
+     */
+    function getFunctions();
+
+    /**
+     * Returns a list of operators to add to the existing list.
+     *
+     * @return array An array of operators
+     */
+    function getOperators();
+
+    /**
+     * Returns a list of global functions to add to the existing list.
+     *
+     * @return array An array of global functions
+     */
+    function getGlobals();
+
+    /**
+     * Returns the name of the extension.
+     *
+     * @return string The extension name
+     */
+    function getName();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Filter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Filter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Filter.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a template filter.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Twig_Filter implements Twig_FilterInterface
+{
+    protected $options;
+
+    public function __construct(array $options = array())
+    {
+        $this->options = array_merge(array(
+            'needs_environment' => false,
+            'needs_context'     => false,
+            'pre_escape'        => null,
+        ), $options);
+    }
+
+    public function needsEnvironment()
+    {
+        return $this->options['needs_environment'];
+    }
+
+    public function needsContext()
+    {
+        return $this->options['needs_context'];
+    }
+
+    public function getSafe(Twig_Node $filterArgs)
+    {
+        if (isset($this->options['is_safe'])) {
+            return $this->options['is_safe'];
+        }
+
+        if (isset($this->options['is_safe_callback'])) {
+            return call_user_func($this->options['is_safe_callback'], $filterArgs);
+        }
+
+        return array();
+    }
+
+    public function getPreEscape()
+    {
+        return $this->options['pre_escape'];
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Function.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a function template filter.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Filter_Function extends Twig_Filter
+{
+    protected $function;
+
+    public function __construct($function, array $options = array())
+    {
+        parent::__construct($options);
+
+        $this->function = $function;
+    }
+
+    public function compile()
+    {
+        return $this->function;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Method.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Method.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Filter/Method.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a method template filter.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Filter_Method extends Twig_Filter
+{
+    protected $extension, $method;
+
+    public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
+    {
+        parent::__construct($options);
+
+        $this->extension = $extension;
+        $this->method = $method;
+    }
+
+    public function compile()
+    {
+        return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/FilterInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/FilterInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/FilterInterface.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a template filter.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_FilterInterface
+{
+    /**
+     * Compiles a filter.
+     *
+     * @return string The PHP code for the filter
+     */
+    function compile();
+
+    function needsEnvironment();
+
+    function needsContext();
+
+    function getSafe(Twig_Node $filterArgs);
+
+    function getPreEscape();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Function.php	(revision 345)
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a template function.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Twig_Function implements Twig_FunctionInterface
+{
+    protected $options;
+
+    public function __construct(array $options = array())
+    {
+        $this->options = array_merge(array(
+            'needs_environment' => false,
+            'needs_context'     => false,
+        ), $options);
+    }
+
+    public function needsEnvironment()
+    {
+        return $this->options['needs_environment'];
+    }
+
+    public function needsContext()
+    {
+        return $this->options['needs_context'];
+    }
+
+    public function getSafe(Twig_Node $functionArgs)
+    {
+        if (isset($this->options['is_safe'])) {
+            return $this->options['is_safe'];
+        }
+
+        if (isset($this->options['is_safe_callback'])) {
+            return call_user_func($this->options['is_safe_callback'], $functionArgs);
+        }
+
+        return array();
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Function.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a function template function.
+ *
+ * @package    twig
+ * @author     Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+class Twig_Function_Function extends Twig_Function
+{
+    protected $function;
+
+    public function __construct($function, array $options = array())
+    {
+        parent::__construct($options);
+
+        $this->function = $function;
+    }
+
+    public function compile()
+    {
+        return $this->function;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Method.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Method.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Function/Method.php	(revision 345)
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a method template function.
+ *
+ * @package    twig
+ * @author     Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+class Twig_Function_Method extends Twig_Function
+{
+    protected $extension, $method;
+
+    public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
+    {
+        parent::__construct($options);
+
+        $this->extension = $extension;
+        $this->method = $method;
+    }
+
+    public function compile()
+    {
+        return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/FunctionInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/FunctionInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/FunctionInterface.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a template function.
+ *
+ * @package    twig
+ * @author     Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+interface Twig_FunctionInterface
+{
+    /**
+     * Compiles a function.
+     *
+     * @return string The PHP code for the function
+     */
+    function compile();
+
+    function needsEnvironment();
+
+    function needsContext();
+
+    function getSafe(Twig_Node $filterArgs);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Lexer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Lexer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Lexer.php	(revision 345)
@@ -0,0 +1,310 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Lexes a template string.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Lexer implements Twig_LexerInterface
+{
+    protected $tokens;
+    protected $code;
+    protected $cursor;
+    protected $lineno;
+    protected $end;
+    protected $state;
+    protected $brackets;
+
+    protected $env;
+    protected $filename;
+    protected $options;
+    protected $operatorRegex;
+
+    const STATE_DATA  = 0;
+    const STATE_BLOCK = 1;
+    const STATE_VAR   = 2;
+
+    const REGEX_NAME   = '/[A-Za-z_][A-Za-z0-9_]*/A';
+    const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
+    const REGEX_STRING = '/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
+    const PUNCTUATION  = '()[]{}?:.,|';
+
+    public function __construct(Twig_Environment $env, array $options = array())
+    {
+        $this->env = $env;
+
+        $this->options = array_merge(array(
+            'tag_comment'  => array('{#', '#}'),
+            'tag_block'    => array('{%', '%}'),
+            'tag_variable' => array('{{', '}}'),
+            'whitespace_trim' => '-'
+        ), $options);
+    }
+
+    /**
+     * Tokenizes a source code.
+     *
+     * @param  string $code     The source code
+     * @param  string $filename A unique identifier for the source code
+     *
+     * @return Twig_TokenStream A token stream instance
+     */
+    public function tokenize($code, $filename = null)
+    {
+        if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+            $mbEncoding = mb_internal_encoding();
+            mb_internal_encoding('ASCII');
+        }
+
+        $this->code = str_replace(array("\r\n", "\r"), "\n", $code);
+        $this->filename = $filename;
+        $this->cursor = 0;
+        $this->lineno = 1;
+        $this->end = strlen($this->code);
+        $this->tokens = array();
+        $this->state = self::STATE_DATA;
+        $this->brackets = array();
+
+        while ($this->cursor < $this->end) {
+            // dispatch to the lexing functions depending
+            // on the current state
+            switch ($this->state) {
+                case self::STATE_DATA:
+                    $this->lexData();
+                    break;
+
+                case self::STATE_BLOCK:
+                    $this->lexBlock();
+                    break;
+
+                case self::STATE_VAR:
+                    $this->lexVar();
+                    break;
+            }
+        }
+
+        $this->pushToken(Twig_Token::EOF_TYPE);
+
+        if (!empty($this->brackets)) {
+            list($expect, $lineno) = array_pop($this->brackets);
+            throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
+        }
+
+        if (isset($mbEncoding)) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return new Twig_TokenStream($this->tokens, $this->filename);
+    }
+
+    protected function lexData()
+    {
+        $pos = $this->end;
+        $append = '';
+
+        // Find the first token after the cursor.
+        foreach (array('tag_comment', 'tag_variable', 'tag_block') as $type) {
+            $tmpPos = strpos($this->code, $this->options[$type][0], $this->cursor);
+            if (false !== $tmpPos && $tmpPos < $pos) {
+                $trimBlock = false;
+                $append = '';
+                $pos = $tmpPos;
+                $token = $this->options[$type][0];
+                if (strpos($this->code, $this->options['whitespace_trim'], $pos) === ($pos + strlen($token))) {
+                    $trimBlock = true;
+                    $append = $this->options['whitespace_trim'];
+                }
+            }
+        }
+
+        // if no matches are left we return the rest of the template as simple text token
+        if ($pos === $this->end) {
+            $this->pushToken(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor));
+            $this->cursor = $this->end;
+            return;
+        }
+        
+        // push the template text first
+        $text = $textContent = substr($this->code, $this->cursor, $pos - $this->cursor);
+        if (true === $trimBlock) {
+            $text = rtrim($text);
+        }
+        $this->pushToken(Twig_Token::TEXT_TYPE, $text);
+        $this->moveCursor($textContent . $token . $append);
+
+        switch ($token) {
+            case $this->options['tag_comment'][0]:
+                $commentEndRegex = '/.*?(?:' . preg_quote($this->options['whitespace_trim'], '/')
+                                   . preg_quote($this->options['tag_comment'][1], '/') . '\s*|'
+                                   . preg_quote($this->options['tag_comment'][1], '/') . ')\n?/As';
+
+                if (!preg_match($commentEndRegex, $this->code, $match, null, $this->cursor)) {
+                    throw new Twig_Error_Syntax('unclosed comment', $this->lineno, $this->filename);
+                }
+
+                $this->moveCursor($match[0]);
+                break;
+
+            case $this->options['tag_block'][0]:
+                // raw data?
+                if (preg_match('/\s*raw\s*'.preg_quote($this->options['tag_block'][1], '/').'(.*?)'.preg_quote($this->options['tag_block'][0], '/').'\s*endraw\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor)) {
+                    $this->pushToken(Twig_Token::TEXT_TYPE, $match[1]);
+                    $this->moveCursor($match[0]);
+                    $this->state = self::STATE_DATA;
+                } else {
+                    $this->pushToken(Twig_Token::BLOCK_START_TYPE);
+                    $this->state = self::STATE_BLOCK;
+                }
+                break;
+
+            case $this->options['tag_variable'][0]:
+                $this->pushToken(Twig_Token::VAR_START_TYPE);
+                $this->state = self::STATE_VAR;
+                break;
+        }
+    }
+
+    protected function lexBlock()
+    {
+        $trimTag = preg_quote($this->options['whitespace_trim'] . $this->options['tag_block'][1], '/');
+        $endTag = preg_quote($this->options['tag_block'][1], '/');
+
+        if (empty($this->brackets) && preg_match('/\s*(?:' . $trimTag . '\s*|\s*' . $endTag . ')\n?/A', $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::BLOCK_END_TYPE);
+            $this->moveCursor($match[0]);
+            $this->state = self::STATE_DATA;
+        }
+        else {
+            $this->lexExpression();
+        }
+    }
+
+    protected function lexVar()
+    {
+        $trimTag = preg_quote($this->options['whitespace_trim'] . $this->options['tag_variable'][1], '/');
+        $endTag = preg_quote($this->options['tag_variable'][1], '/');
+        
+        if (empty($this->brackets) && preg_match('/\s*' . $trimTag . '\s*|\s*' . $endTag . '/A', $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::VAR_END_TYPE);
+            $this->moveCursor($match[0]);
+            $this->state = self::STATE_DATA;
+        }
+        else {
+            $this->lexExpression();
+        }
+    }
+
+    protected function lexExpression()
+    {
+        // whitespace
+        if (preg_match('/\s+/A', $this->code, $match, null, $this->cursor)) {
+            $this->moveCursor($match[0]);
+
+            if ($this->cursor >= $this->end) {
+                throw new Twig_Error_Syntax('Unexpected end of file: Unclosed ' . ($this->state === self::STATE_BLOCK ? 'block' : 'variable'));
+            }
+        }
+
+        // operators
+        if (preg_match($this->getOperatorRegex(), $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]);
+            $this->moveCursor($match[0]);
+        }
+        // names
+        elseif (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::NAME_TYPE, $match[0]);
+            $this->moveCursor($match[0]);
+        }
+        // numbers
+        elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::NUMBER_TYPE, ctype_digit($match[0]) ? (int) $match[0] : (float) $match[0]);
+            $this->moveCursor($match[0]);
+        }
+        // punctuation
+        elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) {
+            // opening bracket
+            if (false !== strpos('([{', $this->code[$this->cursor])) {
+                $this->brackets[] = array($this->code[$this->cursor], $this->lineno);
+            }
+            // closing bracket
+            elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
+                if (empty($this->brackets)) {
+                    throw new Twig_Error_Syntax(sprintf('Unexpected "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
+                }
+
+                list($expect, $lineno) = array_pop($this->brackets);
+                if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
+                    throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
+                }
+            }
+
+            $this->pushToken(Twig_Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
+            ++$this->cursor;
+        }
+        // strings
+        elseif (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) {
+            $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
+            $this->moveCursor($match[0]);
+        }
+        // unlexable
+        else {
+            throw new Twig_Error_Syntax(sprintf("Unexpected character '%s'", $this->code[$this->cursor]), $this->lineno, $this->filename);
+        }
+    }
+
+    protected function pushToken($type, $value = '')
+    {
+        // do not push empty text tokens
+        if (Twig_Token::TEXT_TYPE === $type && '' === $value) {
+            return;
+        }
+
+        $this->tokens[] = new Twig_Token($type, $value, $this->lineno);
+    }
+
+    protected function moveCursor($text)
+    {
+        $this->cursor += strlen($text);
+        $this->lineno += substr_count($text, "\n");
+    }
+
+    protected function getOperatorRegex()
+    {
+        if (null !== $this->operatorRegex) {
+            return $this->operatorRegex;
+        }
+
+        $operators = array_merge(
+            array('='),
+            array_keys($this->env->getUnaryOperators()),
+            array_keys($this->env->getBinaryOperators())
+        );
+
+        $operators = array_combine($operators, array_map('strlen', $operators));
+        arsort($operators);
+
+        $regex = array();
+        foreach ($operators as $operator => $length) {
+            // an operator that ends with a character must be followed by
+            // a whitespace or a parenthesis
+            if (ctype_alpha($operator[$length - 1])) {
+                $regex[] = preg_quote($operator, '/').'(?=[ ()])';
+            } else {
+                $regex[] = preg_quote($operator, '/');
+            }
+        }
+
+        return $this->operatorRegex = '/'.implode('|', $regex).'/A';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/LexerInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/LexerInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/LexerInterface.php	(revision 345)
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by lexer classes.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_LexerInterface
+{
+    /**
+     * Tokenizes a source code.
+     *
+     * @param  string $code     The source code
+     * @param  string $filename A unique identifier for the source code
+     *
+     * @return Twig_TokenStream A token stream instance
+     */
+    function tokenize($code, $filename = null);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Loads a template from an array.
+ *
+ * When using this loader with a cache mechanism, you should know that a new cache
+ * key is generated each time a template content "changes" (the cache key being the
+ * source code of the template). If you don't want to see your cache grows out of
+ * control, you need to take care of clearing the old cache file by yourself.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Loader_Array implements Twig_LoaderInterface
+{
+    protected $templates;
+
+    /**
+     * Constructor.
+     *
+     * @param array $templates An array of templates (keys are the names, and values are the source code)
+     *
+     * @see Twig_Loader
+     */
+    public function __construct(array $templates)
+    {
+        $this->templates = array();
+        foreach ($templates as $name => $template) {
+            $this->templates[$name] = $template;
+        }
+    }
+
+    /**
+     * Gets the source code of a template, given its name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The template source code
+     */
+    public function getSource($name)
+    {
+        if (!isset($this->templates[$name])) {
+            throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
+        }
+
+        return $this->templates[$name];
+    }
+
+    /**
+     * Gets the cache key to use for the cache for a given template name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The cache key
+     */
+    public function getCacheKey($name)
+    {
+        if (!isset($this->templates[$name])) {
+            throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
+        }
+
+        return $this->templates[$name];
+    }
+
+    /**
+     * Returns true if the template is still fresh.
+     *
+     * @param string    $name The template name
+     * @param timestamp $time The last modification time of the cached template
+     */
+    public function isFresh($name, $time)
+    {
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php.new
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php.new	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Array.php.new	(revision 345)
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Loads a template from an array.
+ *
+ * When using this loader with a cache mechanism, you should know that a new cache
+ * key is generated each time a template content "changes" (the cache key being the
+ * source code of the template). If you don't want to see your cache grows out of
+ * control, you need to take care of clearing the old cache file by yourself.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Loader_Array implements Twig_LoaderInterface
+{
+    protected $templates;
+
+    /**
+     * Constructor.
+     *
+     * @param array $templates An array of templates (keys are the names, and values are the source code)
+     *
+     * @see Twig_Loader
+     */
+    public function __construct(array $templates)
+    {
+        $this->templates = array();
+        foreach ($templates as $name => $template) {
+            $this->templates[$name] = $template;
+        }
+    }
+
+    /**
+     * Gets the source code of a template, given its name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The template source code
+     */
+    public function getSource($name)
+    {
+        if (!isset($this->templates[$name])) {
+            throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
+        }
+
+        return $this->templates[$name];
+    }
+
+    /**
+     * Gets the cache key to use for the cache for a given template name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The cache key
+     */
+    public function getCacheKey($name)
+    {
+        if (!isset($this->templates[$name])) {
+            throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
+        }
+
+        return $this->templates[$name];
+    }
+
+    /**
+     * Returns true if the template is still fresh.
+     *
+     * @param string    $name The template name
+     * @param timestamp $time The last modification time of the cached template
+     */
+    public function isFresh($name, $time)
+    {
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Filesystem.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Filesystem.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/Filesystem.php	(revision 345)
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Loads template from the filesystem.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Loader_Filesystem implements Twig_LoaderInterface
+{
+    protected $paths;
+    protected $cache;
+
+    /**
+     * Constructor.
+     *
+     * @param string|array $paths A path or an array of paths where to look for templates
+     */
+    public function __construct($paths)
+    {
+        $this->setPaths($paths);
+    }
+
+    /**
+     * Returns the paths to the templates.
+     *
+     * @return array The array of paths where to look for templates
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Sets the paths where templates are stored.
+     *
+     * @param string|array $paths A path or an array of paths where to look for templates
+     */
+    public function setPaths($paths)
+    {
+        // invalidate the cache
+        $this->cache = array();
+
+        if (!is_array($paths)) {
+            $paths = array($paths);
+        }
+
+        $this->paths = array();
+        foreach ($paths as $path) {
+            if (!is_dir($path)) {
+                throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
+            }
+
+            $this->paths[] = $path;
+        }
+    }
+
+    /**
+     * Gets the source code of a template, given its name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The template source code
+     */
+    public function getSource($name)
+    {
+        return file_get_contents($this->findTemplate($name));
+    }
+
+    /**
+     * Gets the cache key to use for the cache for a given template name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The cache key
+     */
+    public function getCacheKey($name)
+    {
+        return $this->findTemplate($name);
+    }
+
+    /**
+     * Returns true if the template is still fresh.
+     *
+     * @param string    $name The template name
+     * @param timestamp $time The last modification time of the cached template
+     */
+    public function isFresh($name, $time)
+    {
+        return filemtime($this->findTemplate($name)) < $time;
+    }
+
+    protected function findTemplate($name)
+    {
+        // normalize name
+        $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'));
+
+        if (isset($this->cache[$name])) {
+            return $this->cache[$name];
+        }
+
+        $this->validateName($name);
+
+        foreach ($this->paths as $path) {
+            if (is_file($path.'/'.$name)) {
+                return $this->cache[$name] = $path.'/'.$name;
+            }
+        }
+
+        throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths)));
+    }
+
+    protected function validateName($name)
+    {
+        $parts = explode('/', $name);
+        $level = 0;
+        foreach ($parts as $part) {
+            if ('..' === $part) {
+                --$level;
+            } elseif ('.' !== $part) {
+                ++$level;
+            }
+
+            if ($level < 0) {
+                throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/String.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/String.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Loader/String.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Loads a template from a string.
+ *
+ * When using this loader with a cache mechanism, you should know that a new cache
+ * key is generated each time a template content "changes" (the cache key being the
+ * source code of the template). If you don't want to see your cache grows out of
+ * control, you need to take care of clearing the old cache file by yourself.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Loader_String implements Twig_LoaderInterface
+{
+    /**
+     * Gets the source code of a template, given its name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The template source code
+     */
+    public function getSource($name)
+    {
+        return $name;
+    }
+
+    /**
+     * Gets the cache key to use for the cache for a given template name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The cache key
+     */
+    public function getCacheKey($name)
+    {
+        return $name;
+    }
+
+    /**
+     * Returns true if the template is still fresh.
+     *
+     * @param string    $name The template name
+     * @param timestamp $time The last modification time of the cached template
+     */
+    public function isFresh($name, $time)
+    {
+        return true;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/LoaderInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/LoaderInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/LoaderInterface.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface all loaders must implement.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_LoaderInterface
+{
+    /**
+     * Gets the source code of a template, given its name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The template source code
+     */
+    function getSource($name);
+
+    /**
+     * Gets the cache key to use for the cache for a given template name.
+     *
+     * @param  string $name The name of the template to load
+     *
+     * @return string The cache key
+     */
+    function getCacheKey($name);
+
+    /**
+     * Returns true if the template is still fresh.
+     *
+     * @param string    $name The template name
+     * @param timestamp $time The last modification time of the cached template
+     */
+    function isFresh($name, $time);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Markup.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Markup.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Markup.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Marks a content as safe.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Markup
+{
+    protected $content;
+
+    public function __construct($content)
+    {
+        $this->content = (string) $content;
+    }
+
+    public function __toString()
+    {
+        return $this->content;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node.php	(revision 345)
@@ -0,0 +1,227 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a node in the AST.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node implements Twig_NodeInterface, Countable, IteratorAggregate
+{
+    protected $nodes;
+    protected $attributes;
+    protected $lineno;
+    protected $tag;
+
+    /**
+     * Constructor.
+     *
+     * The nodes are automatically made available as properties ($this->node).
+     * The attributes are automatically made available as array items ($this['name']).
+     *
+     * @param array   $nodes      An array of named nodes
+     * @param array   $attributes An array of attributes (should not be nodes)
+     * @param integer $lineno     The line number
+     * @param string  $tag        The tag name associated with the Node
+     */
+    public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
+    {
+        $this->nodes = $nodes;
+        $this->attributes = $attributes;
+        $this->lineno = $lineno;
+        $this->tag = $tag;
+    }
+
+    public function __toString()
+    {
+        $attributes = array();
+        foreach ($this->attributes as $name => $value) {
+            $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
+        }
+
+        $repr = array(get_class($this).'('.implode(', ', $attributes));
+
+        if (count($this->nodes)) {
+            foreach ($this->nodes as $name => $node) {
+                $len = strlen($name) + 4;
+                $noderepr = array();
+                foreach (explode("\n", (string) $node) as $line) {
+                    $noderepr[] = str_repeat(' ', $len).$line;
+                }
+
+                $repr[] = sprintf('  %s: %s', $name, ltrim(implode("\n", $noderepr)));
+            }
+
+            $repr[] = ')';
+        } else {
+            $repr[0] .= ')';
+        }
+
+        return implode("\n", $repr);
+    }
+
+    public function toXml($asDom = false)
+    {
+        $dom = new DOMDocument('1.0', 'UTF-8');
+        $dom->formatOutput = true;
+        $dom->appendChild($xml = $dom->createElement('twig'));
+
+        $xml->appendChild($node = $dom->createElement('node'));
+        $node->setAttribute('class', get_class($this));
+
+        foreach ($this->attributes as $name => $value) {
+            $node->appendChild($attribute = $dom->createElement('attribute'));
+            $attribute->setAttribute('name', $name);
+            $attribute->appendChild($dom->createTextNode($value));
+        }
+
+        foreach ($this->nodes as $name => $n) {
+            if (null === $n) {
+                continue;
+            }
+
+            $child = $n->toXml(true)->getElementsByTagName('node')->item(0);
+            $child = $dom->importNode($child, true);
+            $child->setAttribute('name', $name);
+
+            $node->appendChild($child);
+        }
+
+        return $asDom ? $dom : $dom->saveXml();
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        foreach ($this->nodes as $node) {
+            $node->compile($compiler);
+        }
+    }
+
+    public function getLine()
+    {
+        return $this->lineno;
+    }
+
+    public function getNodeTag()
+    {
+        return $this->tag;
+    }
+
+    /**
+     * Returns true if the attribute is defined.
+     *
+     * @param  string  The attribute name
+     *
+     * @return Boolean true if the attribute is defined, false otherwise
+     */
+    public function hasAttribute($name)
+    {
+        return array_key_exists($name, $this->attributes);
+    }
+
+    /**
+     * Gets an attribute.
+     *
+     * @param  string The attribute name
+     *
+     * @return mixed  The attribute value
+     */
+    public function getAttribute($name)
+    {
+        if (!array_key_exists($name, $this->attributes)) {
+            throw new Twig_Error_Runtime(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
+        }
+
+        return $this->attributes[$name];
+    }
+
+    /**
+     * Sets an attribute.
+     *
+     * @param string The attribute name
+     * @param mixed  The attribute value
+     */
+    public function setAttribute($name, $value)
+    {
+        $this->attributes[$name] = $value;
+    }
+
+    /**
+     * Removes an attribute.
+     *
+     * @param string The attribute name
+     */
+    public function removeAttribute($name)
+    {
+        unset($this->attributes[$name]);
+    }
+
+    /**
+     * Returns true if the node with the given identifier exists.
+     *
+     * @param  string  The node name
+     *
+     * @return Boolean true if the node with the given name exists, false otherwise
+     */
+    public function hasNode($name)
+    {
+        return array_key_exists($name, $this->nodes);
+    }
+
+    /**
+     * Gets a node by name.
+     *
+     * @param  string The node name
+     *
+     * @return Twig_Node A Twig_Node instance
+     */
+    public function getNode($name)
+    {
+        if (!array_key_exists($name, $this->nodes)) {
+            throw new Twig_Error_Runtime(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
+        }
+
+        return $this->nodes[$name];
+    }
+
+    /**
+     * Sets a node.
+     *
+     * @param string    The node name
+     * @param Twig_Node A Twig_Node instance
+     */
+    public function setNode($name, $node = null)
+    {
+        $this->nodes[$name] = $node;
+    }
+
+    /**
+     * Removes a node by name.
+     *
+     * @param string The node name
+     */
+    public function removeNode($name)
+    {
+        unset($this->nodes[$name]);
+    }
+
+    public function count()
+    {
+        return count($this->nodes);
+    }
+
+    public function getIterator()
+    {
+        return new ArrayIterator($this->nodes);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/AutoEscape.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/AutoEscape.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/AutoEscape.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents an autoescape node.
+ *
+ * The value is the escaping strategy (can be html, js, ...)
+ *
+ * The true value is equivalent to html.
+ *
+ * If autoescaping is disabled, then the value is false.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_AutoEscape extends Twig_Node
+{
+    public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
+    {
+        parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->subcompile($this->getNode('body'));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Block.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Block.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Block.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a block node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Block extends Twig_Node
+{
+    public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
+    {
+        parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write(sprintf("public function block_%s(\$context, array \$blocks = array())\n", $this->getAttribute('name')), "{\n")
+            ->indent()
+        ;
+
+        $compiler
+            ->subcompile($this->getNode('body'))
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/BlockReference.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/BlockReference.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/BlockReference.php	(revision 345)
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a block call node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface
+{
+    public function __construct($name, $lineno, $tag = null)
+    {
+        parent::__construct(array(), array('name' => $name), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression.php	(revision 345)
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Abstract class for all nodes that represents an expression.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Twig_Node_Expression extends Twig_Node
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Array.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Array.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Array.php	(revision 345)
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Array extends Twig_Node_Expression
+{
+    public function __construct(array $elements, $lineno)
+    {
+        parent::__construct($elements, array(), $lineno);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->raw('array(');
+        $first = true;
+        foreach ($this->nodes as $name => $node) {
+            if (!$first) {
+                $compiler->raw(', ');
+            }
+            $first = false;
+
+            $compiler
+                ->repr($name)
+                ->raw(' => ')
+                ->subcompile($node)
+            ;
+        }
+        $compiler->raw(')');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/AssignName.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/AssignName.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/AssignName.php	(revision 345)
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->raw(sprintf('$context[\'%s\']', $this->getAttribute('name')));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
+{
+    public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
+    {
+        parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('(')
+            ->subcompile($this->getNode('left'))
+            ->raw(' ')
+        ;
+        $this->operator($compiler);
+        $compiler
+            ->raw(' ')
+            ->subcompile($this->getNode('right'))
+            ->raw(')')
+        ;
+    }
+
+    abstract public function operator(Twig_Compiler $compiler);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Add.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Add.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Add.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('+');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/And.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/And.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/And.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('&&');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Concat.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Concat.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Concat.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('.');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Div.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Div.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Div.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('/');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Equal.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Equal.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Equal.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('==');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/FloorDiv.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/FloorDiv.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/FloorDiv.php	(revision 345)
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->raw('floor(');
+        parent::compile($compiler);
+        $compiler->raw(')');
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('/');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Greater.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Greater.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Greater.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('>');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/GreaterEqual.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/GreaterEqual.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/GreaterEqual.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('>=');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/In.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/In.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/In.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('twig_in_filter(')
+            ->subcompile($this->getNode('left'))
+            ->raw(', ')
+            ->subcompile($this->getNode('right'))
+            ->raw(')')
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('in');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Less.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Less.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Less.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('<');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/LessEqual.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/LessEqual.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/LessEqual.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('<=');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mod.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mod.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mod.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('%');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mul.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mul.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Mul.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('*');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotEqual.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotEqual.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotEqual.php	(revision 345)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('!=');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotIn.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotIn.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/NotIn.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('!twig_in_filter(')
+            ->subcompile($this->getNode('left'))
+            ->raw(', ')
+            ->subcompile($this->getNode('right'))
+            ->raw(')')
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('not in');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Or.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Or.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Or.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('||');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Power.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Power.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Power.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('pow(')
+            ->subcompile($this->getNode('left'))
+            ->raw(', ')
+            ->subcompile($this->getNode('right'))
+            ->raw(')')
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('**');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Range.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Range.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Range.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('range(')
+            ->subcompile($this->getNode('left'))
+            ->raw(', ')
+            ->subcompile($this->getNode('right'))
+            ->raw(')')
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('..');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Sub.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Sub.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Binary/Sub.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('-');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/BlockReference.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/BlockReference.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/BlockReference.php	(revision 345)
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a block call node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
+{
+    public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null)
+    {
+        parent::__construct(array('name' => $name), array('as_string' => $asString), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        if ($this->getAttribute('as_string')) {
+            $compiler->raw('(string) ');
+        }
+
+        $compiler
+            ->raw("\$this->renderBlock(")
+            ->subcompile($this->getNode('name'))
+            ->raw(", \$context, \$blocks)")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Conditional.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Conditional.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Conditional.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Conditional extends Twig_Node_Expression
+{
+    public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno)
+    {
+        parent::__construct(array('expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3), array(), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('((')
+            ->subcompile($this->getNode('expr1'))
+            ->raw(') ? (')
+            ->subcompile($this->getNode('expr2'))
+            ->raw(') : (')
+            ->subcompile($this->getNode('expr3'))
+            ->raw('))')
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Constant.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Constant.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Constant.php	(revision 345)
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Constant extends Twig_Node_Expression
+{
+    public function __construct($value, $lineno)
+    {
+        parent::__construct(array(), array('value' => $value), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->repr($this->getAttribute('value'));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/ExtensionReference.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/ExtensionReference.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/ExtensionReference.php	(revision 345)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents an extension call node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
+{
+    public function __construct($name, $lineno, $tag = null)
+    {
+        parent::__construct(array(), array('name' => $name), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Filter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Filter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Filter.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Filter extends Twig_Node_Expression
+{
+    public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
+    {
+        parent::__construct(array('node' => $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $name = $this->getNode('filter')->getAttribute('value');
+        if (false === $filter = $compiler->getEnvironment()->getFilter($name)) {
+            throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine());
+        }
+
+        // The default filter is intercepted when the filtered value
+        // is a name (like obj) or an attribute (like obj.attr)
+        // In such a case, it's compiled to {{ obj is defined ? obj|default('bar') : 'bar' }}
+        if ('default' === $name && ($this->getNode('node') instanceof Twig_Node_Expression_Name || $this->getNode('node') instanceof Twig_Node_Expression_GetAttr)) {
+            $compiler->raw('((');
+            if ($this->getNode('node') instanceof Twig_Node_Expression_Name) {
+                $testMap = $compiler->getEnvironment()->getTests();
+                $compiler
+                    ->raw($testMap['defined']->compile().'(')
+                    ->repr($this->getNode('node')->getAttribute('name'))
+                    ->raw(', $context)')
+                ;
+            } elseif ($this->getNode('node') instanceof Twig_Node_Expression_GetAttr) {
+                $this->getNode('node')->setAttribute('is_defined_test', true);
+                $compiler->subcompile($this->getNode('node'));
+            }
+
+            $compiler->raw(') ? (');
+            $this->compileFilter($compiler, $filter);
+            $compiler->raw(') : (');
+            $compiler->subcompile($this->getNode('arguments')->getNode(0));
+            $compiler->raw('))');
+        } else {
+            $this->compileFilter($compiler, $filter);
+        }
+    }
+
+    protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter)
+    {
+        $compiler
+            ->raw($filter->compile().'(')
+            ->raw($filter->needsEnvironment() ? '$this->env, ' : '')
+            ->raw($filter->needsContext() ? '$context, ' : '')
+        ;
+
+        $this->getNode('node')->compile($compiler);
+
+        foreach ($this->getNode('arguments') as $node) {
+            $compiler
+                ->raw(', ')
+                ->subcompile($node)
+            ;
+        }
+
+        $compiler->raw(')');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Function.php	(revision 345)
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Function extends Twig_Node_Expression
+{
+    public function __construct(Twig_Node_Expression_Name $name, Twig_NodeInterface $arguments, $lineno)
+    {
+        parent::__construct(array('name' => $name, 'arguments' => $arguments), array(), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $function = $compiler->getEnvironment()->getFunction($this->getNode('name')->getAttribute('name'));
+        if (false === $function) {
+            throw new Twig_Error_Syntax(sprintf('The function "%s" does not exist', $this->getNode('name')->getAttribute('name')), $this->getLine());
+        }
+
+        $compiler
+            ->raw($function->compile().'(')
+            ->raw($function->needsEnvironment() ? '$this->env' : '')
+        ;
+
+        if ($function->needsContext()) {
+            $compiler->raw($function->needsEnvironment() ? ', $context' : '$context');
+        }
+
+        $first = true;
+        foreach ($this->getNode('arguments') as $node) {
+            if (!$first) {
+                $compiler->raw(', ');
+            } else {
+                if ($function->needsEnvironment() || $function->needsContext()) {
+                    $compiler->raw(', ');
+                }
+                $first = false;
+            }
+            $compiler->subcompile($node);
+        }
+
+        $compiler->raw(')');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/GetAttr.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/GetAttr.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/GetAttr.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
+{
+    public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_NodeInterface $arguments, $type, $lineno)
+    {
+        parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('$this->getAttribute(')
+            ->subcompile($this->getNode('node'))
+            ->raw(', ')
+            ->subcompile($this->getNode('attribute'))
+            ->raw(', array(')
+        ;
+
+        foreach ($this->getNode('arguments') as $node) {
+            $compiler
+                ->subcompile($node)
+                ->raw(', ')
+            ;
+        }
+
+        $compiler
+            ->raw('), ')
+            ->repr($this->getAttribute('type'))
+            ->raw($this->hasAttribute('is_defined_test') ? ', true' : ', false')
+            ->raw(')');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Name.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Name.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Name.php	(revision 345)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Name extends Twig_Node_Expression
+{
+    public function __construct($name, $lineno)
+    {
+        parent::__construct(array(), array('name' => $name), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        if ('_self' === $this->getAttribute('name')) {
+            $compiler->raw('$this');
+        } elseif ('_context' === $this->getAttribute('name')) {
+            $compiler->raw('$context');
+        } elseif ('_charset' === $this->getAttribute('name')) {
+            $compiler->raw('$this->env->getCharset()');
+        } elseif ($compiler->getEnvironment()->isStrictVariables()) {
+            $compiler->raw(sprintf('$this->getContext($context, \'%s\')', $this->getAttribute('name')));
+        } else {
+            $compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->getAttribute('name'), $this->getAttribute('name')));
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Parent.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Parent.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Parent.php	(revision 345)
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a parent node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Expression_Parent extends Twig_Node_Expression
+{
+    public function __construct($name, $lineno, $tag = null)
+    {
+        parent::__construct(array(), array('name' => $name), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw("\$this->renderParentBlock(")
+            ->string($this->getAttribute('name'))
+            ->raw(", \$context, \$blocks)")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Test.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Test.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Test.php	(revision 345)
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Test extends Twig_Node_Expression
+{
+    public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
+    {
+        parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $testMap = $compiler->getEnvironment()->getTests();
+        if (!isset($testMap[$this->getAttribute('name')])) {
+            throw new Twig_Error_Syntax(sprintf('The test "%s" does not exist', $this->getAttribute('name')), $this->getLine());
+        }
+
+        // defined is a special case
+        if ('defined' === $this->getAttribute('name')) {
+            if ($this->getNode('node') instanceof Twig_Node_Expression_Name) {
+                $compiler
+                    ->raw($testMap['defined']->compile().'(')
+                    ->repr($this->getNode('node')->getAttribute('name'))
+                    ->raw(', $context)')
+                ;
+            } elseif ($this->getNode('node') instanceof Twig_Node_Expression_GetAttr) {
+                $this->getNode('node')->setAttribute('is_defined_test', true);
+                $compiler->subcompile($this->getNode('node'));
+            } else {
+                throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
+            }
+            return;
+        }
+
+        $compiler
+            ->raw($testMap[$this->getAttribute('name')]->compile().'(')
+            ->subcompile($this->getNode('node'))
+        ;
+
+        if (null !== $this->getNode('arguments')) {
+            $compiler->raw(', ');
+
+            $max = count($this->getNode('arguments')) - 1;
+            foreach ($this->getNode('arguments') as $i => $node) {
+                $compiler->subcompile($node);
+
+                if ($i != $max) {
+                    $compiler->raw(', ');
+                }
+            }
+        }
+
+        $compiler->raw(')');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
+{
+    public function __construct(Twig_NodeInterface $node, $lineno)
+    {
+        parent::__construct(array('node' => $node), array(), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->raw('(');
+        $this->operator($compiler);
+        $compiler
+            ->subcompile($this->getNode('node'))
+            ->raw(')')
+        ;
+    }
+
+    abstract public function operator(Twig_Compiler $compiler);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Neg.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Neg.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Neg.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        $compiler->raw('-');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Not.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Not.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Not.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        $compiler->raw('!');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Pos.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Pos.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Expression/Unary/Pos.php	(revision 345)
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
+{
+    public function operator(Twig_Compiler $compiler)
+    {
+        $compiler->raw('+');
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/For.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/For.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/For.php	(revision 345)
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a for node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_For extends Twig_Node
+{
+    public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
+    {
+        parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            // the (array) cast bypasses a PHP 5.2.6 bug
+            ->write("\$context['_parent'] = (array) \$context;\n")
+            ->write("\$context['_seq'] = twig_ensure_traversable(")
+            ->subcompile($this->getNode('seq'))
+            ->raw(");\n")
+        ;
+
+        if (null !== $this->getNode('else')) {
+            $compiler->write("\$context['_iterated'] = false;\n");
+        }
+
+        if ($this->getAttribute('with_loop')) {
+            $compiler
+                ->write("\$context['loop'] = array(\n")
+                ->write("  'parent' => \$context['_parent'],\n")
+                ->write("  'index0' => 0,\n")
+                ->write("  'index'  => 1,\n")
+                ->write("  'first'  => true,\n")
+                ->write(");\n")
+                ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n")
+                ->indent()
+                ->write("\$length = count(\$context['_seq']);\n")
+                ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
+                ->write("\$context['loop']['revindex'] = \$length;\n")
+                ->write("\$context['loop']['length'] = \$length;\n")
+                ->write("\$context['loop']['last'] = 1 === \$length;\n")
+                ->outdent()
+                ->write("}\n")
+            ;
+        }
+
+        $compiler
+            ->write("foreach (\$context['_seq'] as ")
+            ->subcompile($this->getNode('key_target'))
+            ->raw(" => ")
+            ->subcompile($this->getNode('value_target'))
+            ->raw(") {\n")
+            ->indent()
+        ;
+
+        $compiler->subcompile($this->getNode('body'));
+
+        if (null !== $this->getNode('else')) {
+            $compiler->write("\$context['_iterated'] = true;\n");
+        }
+
+        if ($this->getAttribute('with_loop')) {
+            $compiler
+                ->write("++\$context['loop']['index0'];\n")
+                ->write("++\$context['loop']['index'];\n")
+                ->write("\$context['loop']['first'] = false;\n")
+                ->write("if (isset(\$context['loop']['length'])) {\n")
+                ->indent()
+                ->write("--\$context['loop']['revindex0'];\n")
+                ->write("--\$context['loop']['revindex'];\n")
+                ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
+                ->outdent()
+                ->write("}\n")
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write("}\n")
+        ;
+
+        if (null !== $this->getNode('else')) {
+            $compiler
+                ->write("if (!\$context['_iterated']) {\n")
+                ->indent()
+                ->subcompile($this->getNode('else'))
+                ->outdent()
+                ->write("}\n")
+            ;
+        }
+
+        $compiler->write("\$_parent = \$context['_parent'];\n");
+
+        // remove some "private" loop variables (needed for nested loops)
+        $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n");
+
+        // keep the values set in the inner context for variables defined in the outer context
+        $compiler->write("\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));\n");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/If.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/If.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/If.php	(revision 345)
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents an if node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_If extends Twig_Node
+{
+    public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
+    {
+        parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->addDebugInfo($this);
+        for ($i = 0; $i < count($this->getNode('tests')); $i += 2) {
+            if ($i > 0) {
+                $compiler
+                    ->outdent()
+                    ->write("} elseif (")
+                ;
+            } else {
+                $compiler
+                    ->write('if (')
+                ;
+            }
+
+            $compiler
+                ->subcompile($this->getNode('tests')->getNode($i))
+                ->raw(") {\n")
+                ->indent()
+                ->subcompile($this->getNode('tests')->getNode($i + 1))
+            ;
+        }
+
+        if ($this->hasNode('else') && null !== $this->getNode('else')) {
+            $compiler
+                ->outdent()
+                ->write("} else {\n")
+                ->indent()
+                ->subcompile($this->getNode('else'))
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write("}\n");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Import.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Import.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Import.php	(revision 345)
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents an import node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Import extends Twig_Node
+{
+    public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $var, $lineno, $tag = null)
+    {
+        parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write('')
+            ->subcompile($this->getNode('var'))
+            ->raw(' = ')
+        ;
+
+        if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) {
+            $compiler->raw("\$this");
+        } else {
+            $compiler
+                ->raw('$this->env->loadTemplate(')
+                ->subcompile($this->getNode('expr'))
+                ->raw(")")
+            ;
+        }
+
+        $compiler->raw(";\n");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Include.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Include.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Include.php	(revision 345)
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents an include node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
+{
+    public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $lineno, $tag = null)
+    {
+        parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->addDebugInfo($this);
+
+        if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) {
+            $compiler
+                ->write("\$this->env->loadTemplate(")
+                ->subcompile($this->getNode('expr'))
+                ->raw(")->display(")
+            ;
+        } else {
+            $compiler
+                ->write("\$template = ")
+                ->subcompile($this->getNode('expr'))
+                ->raw(";\n")
+                ->write("if (!\$template")
+                ->raw(" instanceof Twig_Template) {\n")
+                ->indent()
+                ->write("\$template = \$this->env->loadTemplate(\$template);\n")
+                ->outdent()
+                ->write("}\n")
+                ->write('$template->display(')
+            ;
+        }
+
+        if (false === $this->getAttribute('only')) {
+            if (null === $this->getNode('variables')) {
+                $compiler->raw('$context');
+            } else {
+                $compiler
+                    ->raw('array_merge($context, ')
+                    ->subcompile($this->getNode('variables'))
+                    ->raw(')')
+                ;
+            }
+        } else {
+            if (null === $this->getNode('variables')) {
+                $compiler->raw('array()');
+            } else {
+                $compiler->subcompile($this->getNode('variables'));
+            }
+        }
+
+        $compiler->raw(");\n");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Macro.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Macro.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Macro.php	(revision 345)
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a macro node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Macro extends Twig_Node
+{
+    public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
+    {
+        parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $arguments = array();
+        foreach ($this->getNode('arguments') as $argument) {
+            $arguments[] = '$'.$argument->getAttribute('name').' = null';
+        }
+
+        $compiler
+            ->addDebugInfo($this)
+            ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n")
+            ->indent()
+            ->write("\$context = array_merge(\$this->env->getGlobals(), array(\n")
+            ->indent()
+        ;
+
+        foreach ($this->getNode('arguments') as $argument) {
+            $compiler
+                ->write('')
+                ->string($argument->getAttribute('name'))
+                ->raw(' => $'.$argument->getAttribute('name'))
+                ->raw(",\n")
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write("));\n\n")
+            ->write("ob_start();\n")
+            ->subcompile($this->getNode('body'))
+            ->raw("\n")
+            ->write("return ob_get_clean();\n")
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Module.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Module.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Module.php	(revision 345)
@@ -0,0 +1,205 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a module node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Module extends Twig_Node
+{
+    public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, $filename)
+    {
+        parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros), array('filename' => $filename), 1);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $this->compileTemplate($compiler);
+    }
+
+    protected function compileTemplate(Twig_Compiler $compiler)
+    {
+        $this->compileClassHeader($compiler);
+
+        if (count($this->getNode('blocks'))) {
+            $this->compileConstructor($compiler);
+        }
+
+        $this->compileGetParent($compiler);
+
+        $this->compileDisplayHeader($compiler);
+
+        $this->compileDisplayBody($compiler);
+
+        $this->compileDisplayFooter($compiler);
+
+        $compiler->subcompile($this->getNode('blocks'));
+
+        $this->compileMacros($compiler);
+
+        $this->compileGetTemplateName($compiler);
+
+        $this->compileClassFooter($compiler);
+    }
+
+    protected function compileGetParent(Twig_Compiler $compiler)
+    {
+        if (null === $this->getNode('parent')) {
+            return;
+        }
+
+        $compiler
+            ->write("public function getParent(array \$context)\n", "{\n")
+            ->indent()
+            ->write("if (null === \$this->parent) {\n")
+            ->indent();
+        ;
+
+        if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
+            $compiler
+                ->write("\$this->parent = \$this->env->loadTemplate(")
+                ->subcompile($this->getNode('parent'))
+                ->raw(");\n")
+            ;
+        } else {
+            $compiler
+                ->write("\$this->parent = ")
+                ->subcompile($this->getNode('parent'))
+                ->raw(";\n")
+                ->write("if (!\$this->parent")
+                ->raw(" instanceof Twig_Template) {\n")
+                ->indent()
+                ->write("\$this->parent = \$this->env->loadTemplate(\$this->parent);\n")
+                ->outdent()
+                ->write("}\n")
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write("}\n\n")
+            ->write("return \$this->parent;\n")
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+
+    protected function compileDisplayBody(Twig_Compiler $compiler)
+    {
+        $compiler->write("\$context = array_merge(\$this->env->getGlobals(), \$context);\n\n");
+
+        if (null !== $this->getNode('parent')) {
+            // remove all output nodes
+            foreach ($this->getNode('body') as $node) {
+                if (!$node instanceof Twig_NodeOutputInterface) {
+                    $compiler->subcompile($node);
+                }
+            }
+
+            $compiler
+                ->write("\$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks));\n")
+            ;
+        } else {
+            $compiler->subcompile($this->getNode('body'));
+        }
+    }
+
+    protected function compileClassHeader(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write("<?php\n\n")
+            // if the filename contains */, add a blank to avoid a PHP parse error
+            ->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
+            ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename')))
+            ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
+            ->write("{\n")
+            ->indent()
+        ;
+
+        if (null !== $this->getNode('parent')) {
+            $compiler->write("protected \$parent;\n\n");
+        }
+    }
+
+    protected function compileConstructor(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write("public function __construct(Twig_Environment \$env)\n", "{\n")
+            ->indent()
+            ->write("parent::__construct(\$env);\n\n")
+            ->write("\$this->blocks = array(\n")
+            ->indent()
+        ;
+
+        foreach ($this->getNode('blocks') as $name => $node) {
+            $compiler
+                ->write(sprintf("'%s' => array(\$this, 'block_%s'),\n", $name, $name))
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write(");\n")
+            ->outdent()
+            ->write("}\n\n");
+        ;
+    }
+
+    protected function compileDisplayHeader(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
+            ->indent()
+        ;
+    }
+
+    protected function compileDisplayFooter(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+
+    protected function compileClassFooter(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->outdent()
+            ->write("}\n")
+        ;
+    }
+
+    protected function compileMacros(Twig_Compiler $compiler)
+    {
+        $compiler->subcompile($this->getNode('macros'));
+    }
+
+    protected function compileGetTemplateName(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write("public function getTemplateName()\n", "{\n")
+            ->indent()
+            ->write('return ')
+            ->repr($this->getAttribute('filename'))
+            ->raw(";\n")
+            ->outdent()
+            ->write("}\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Print.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Print.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Print.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a node that outputs an expression.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
+{
+    public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
+    {
+        parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write('echo ')
+            ->subcompile($this->getNode('expr'))
+            ->raw(";\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Sandbox.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Sandbox.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Sandbox.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a sandbox node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Sandbox extends Twig_Node
+{
+    public function __construct(Twig_NodeInterface $body, $lineno, $tag = null)
+    {
+        parent::__construct(array('body' => $body), array(), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
+            ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
+            ->indent()
+            ->write("\$sandbox->enableSandbox();\n")
+            ->outdent()
+            ->write("}\n")
+            ->subcompile($this->getNode('body'))
+            ->write("if (!\$alreadySandboxed) {\n")
+            ->indent()
+            ->write("\$sandbox->disableSandbox();\n")
+            ->outdent()
+            ->write("}\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedModule.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedModule.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedModule.php	(revision 345)
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a module node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_SandboxedModule extends Twig_Node_Module
+{
+    protected $usedFilters;
+    protected $usedTags;
+    protected $usedFunctions;
+
+    public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions)
+    {
+        parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag());
+
+        $this->usedFilters = $usedFilters;
+        $this->usedTags = $usedTags;
+        $this->usedFunctions = $usedFunctions;
+    }
+
+    protected function compileDisplayBody(Twig_Compiler $compiler)
+    {
+        if (null === $this->getNode('parent')) {
+            $compiler->write("\$this->checkSecurity();\n");
+        }
+
+        parent::compileDisplayBody($compiler);
+    }
+
+    protected function compileDisplayFooter(Twig_Compiler $compiler)
+    {
+        parent::compileDisplayFooter($compiler);
+
+        $compiler
+            ->write("protected function checkSecurity() {\n")
+            ->indent()
+            ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
+            ->indent()
+            ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n")
+            ->write(!$this->usedFilters ? "array(),\n" : "array('".implode('\', \'', $this->usedFilters)."'),\n")
+            ->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n")
+            ->outdent()
+            ->write(");\n")
+        ;
+
+        if (null !== $this->getNode('parent')) {
+            $compiler
+                ->raw("\n")
+                ->write("\$this->parent->checkSecurity();\n")
+            ;
+        }
+
+        $compiler
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedPrint.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedPrint.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/SandboxedPrint.php	(revision 345)
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_Node_SandboxedPrint adds a check for the __toString() method
+ * when the variable is an object and the sandbox is activated.
+ *
+ * When there is a simple Print statement, like {{ article }},
+ * and if the sandbox is enabled, we need to check that the __toString()
+ * method is allowed if 'article' is an object.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_SandboxedPrint extends Twig_Node_Print
+{
+    public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
+    {
+        parent::__construct($expr, $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(')
+            ->subcompile($this->getNode('expr'))
+            ->raw(");\n")
+        ;
+    }
+
+    /**
+     * Removes node filters.
+     *
+     * This is mostly needed when another visitor adds filters (like the escaper one).
+     *
+     * @param Twig_Node $node A Node
+     */
+    protected function removeNodeFilter($node)
+    {
+        if ($node instanceof Twig_Node_Expression_Filter) {
+            return $this->removeNodeFilter($node->getNode('node'));
+        }
+
+        return $node;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Set.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Set.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Set.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a set node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Set extends Twig_Node
+{
+    public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null)
+    {
+        parent::__construct(array('names' => $names, 'values' => $values), array('capture' => $capture), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler->addDebugInfo($this);
+
+        if (count($this->getNode('names')) > 1) {
+            $compiler->write('list(');
+            foreach ($this->getNode('names') as $idx => $node) {
+                if ($idx) {
+                    $compiler->raw(', ');
+                }
+
+                $compiler->subcompile($node);
+            }
+            $compiler->raw(')');
+        } else {
+            if ($this->getAttribute('capture')) {
+                $compiler
+                    ->write("ob_start();\n")
+                    ->subcompile($this->getNode('values'))
+                ;
+            }
+
+            $compiler->subcompile($this->getNode('names'), false);
+
+            if ($this->getAttribute('capture')) {
+                $compiler->raw(" = new Twig_Markup(ob_get_clean())");
+            }
+        }
+
+        if (!$this->getAttribute('capture')) {
+            $compiler->raw(' = ');
+
+            if (count($this->getNode('names')) > 1) {
+                $compiler->write('array(');
+                foreach ($this->getNode('values') as $idx => $value) {
+                    if ($idx) {
+                        $compiler->raw(', ');
+                    }
+
+                    $compiler->subcompile($value);
+                }
+                $compiler->raw(')');
+            } else {
+                $compiler->subcompile($this->getNode('values'));
+            }
+        }
+
+        $compiler->raw(";\n");
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Spaceless.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Spaceless.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Spaceless.php	(revision 345)
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a spaceless node.
+ *
+ * It removes spaces between HTML tags.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Spaceless extends Twig_Node
+{
+    public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
+    {
+        parent::__construct(array('body' => $body), array(), $lineno, $tag);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write("ob_start();\n")
+            ->subcompile($this->getNode('body'))
+            ->write("echo trim(preg_replace('/>\s+</', '><', ob_get_clean()));\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Text.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Text.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Node/Text.php	(revision 345)
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a text node.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
+{
+    public function __construct($data, $lineno)
+    {
+        parent::__construct(array(), array('data' => $data), $lineno);
+    }
+
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->addDebugInfo($this)
+            ->write('echo ')
+            ->string($this->getAttribute('data'))
+            ->raw(";\n")
+        ;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeInterface.php	(revision 345)
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a node in the AST.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_NodeInterface
+{
+    /**
+     * Compiles the node to PHP.
+     *
+     * @param Twig_Compiler A Twig_Compiler instance
+     */
+    function compile(Twig_Compiler $compiler);
+
+    function getLine();
+
+    function getNodeTag();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeOutputInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeOutputInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeOutputInterface.php	(revision 345)
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a displayable node in the AST.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_NodeOutputInterface
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeTraverser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeTraverser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeTraverser.php	(revision 345)
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_NodeTraverser is a node traverser.
+ *
+ * It visits all nodes and their children and call the given visitor for each.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_NodeTraverser
+{
+    protected $env;
+    protected $visitors;
+
+    /**
+     * Constructor.
+     *
+     * @param Twig_Environment $env      A Twig_Environment instance
+     * @param array            $visitors An array of Twig_NodeVisitorInterface instances
+     */
+    public function __construct(Twig_Environment $env, array $visitors = array())
+    {
+        $this->env = $env;
+        $this->visitors = array();
+        foreach ($visitors as $visitor) {
+            $this->addVisitor($visitor);
+        }
+    }
+
+    /**
+     * Adds a visitor.
+     *
+     * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance
+     */
+    public function addVisitor(Twig_NodeVisitorInterface $visitor)
+    {
+        if (!isset($this->visitors[$visitor->getPriority()])) {
+            $this->visitors[$visitor->getPriority()] = array();
+        }
+
+        $this->visitors[$visitor->getPriority()][] = $visitor;
+    }
+
+    /**
+     * Traverses a node and calls the registered visitors.
+     *
+     * @param Twig_NodeInterface $node A Twig_NodeInterface instance
+     */
+    public function traverse(Twig_NodeInterface $node)
+    {
+        ksort($this->visitors);
+        foreach ($this->visitors as $visitors) {
+            foreach ($visitors as $visitor) {
+                $node = $this->traverseForVisitor($visitor, $node);
+            }
+        }
+
+        return $node;
+    }
+
+    protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null)
+    {
+        if (null === $node) {
+            return null;
+        }
+
+        $node = $visitor->enterNode($node, $this->env);
+
+        foreach ($node as $k => $n) {
+            if (false !== $n = $this->traverseForVisitor($visitor, $n)) {
+                $node->setNode($k, $n);
+            } else {
+                $node->removeNode($k);
+            }
+        }
+
+        return $visitor->leaveNode($node, $this->env);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Escaper.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Escaper.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Escaper.php	(revision 345)
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_NodeVisitor_Escaper implements output escaping.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
+{
+    protected $statusStack = array();
+    protected $blocks = array();
+
+    protected $safeAnalysis;
+    protected $traverser;
+
+    function __construct()
+    {
+        $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
+    }
+
+    /**
+     * Called before child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_AutoEscape) {
+            $this->statusStack[] = $node->getAttribute('value');
+        } elseif ($node instanceof Twig_Node_Block) {
+            $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
+        }
+
+        return $node;
+    }
+
+    /**
+     * Called after child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_Expression_Filter) {
+            return $this->preEscapeFilterNode($node, $env);
+        } elseif ($node instanceof Twig_Node_Print) {
+            return $this->escapePrintNode($node, $env, $this->needEscaping($env));
+        }
+
+        if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
+            array_pop($this->statusStack);
+        } elseif ($node instanceof Twig_Node_BlockReference) {
+            $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
+        }
+
+        return $node;
+    }
+
+    protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type)
+    {
+        if (false === $type) {
+            return $node;
+        }
+
+        $expression = $node->getNode('expr');
+
+        if ($this->isSafeFor($type, $expression, $env)) {
+            return $node;
+        }
+
+        $class = get_class($node);
+
+        return new $class(
+            $this->getEscaperFilter($type, $expression),
+            $node->getLine()
+        );
+    }
+
+    protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env)
+    {
+        $name = $filter->getNode('filter')->getAttribute('value');
+
+        if (false !== $f = $env->getFilter($name)) {
+            $type = $f->getPreEscape();
+            if (null === $type) {
+                return $filter;
+            }
+
+            $node = $filter->getNode('node');
+            if ($this->isSafeFor($type, $node, $env)) {
+                return $filter;
+            }
+
+            $filter->setNode('node', $this->getEscaperFilter($type, $node));
+
+            return $filter;
+        }
+
+        return $filter;
+    }
+
+    protected function isSafeFor($type, Twig_NodeInterface $expression, $env)
+    {
+        $safe = $this->safeAnalysis->getSafe($expression);
+
+        if (null === $safe) {
+            if (null === $this->traverser) {
+                $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis));
+            }
+            $this->traverser->traverse($expression);
+            $safe = $this->safeAnalysis->getSafe($expression);
+        }
+
+        return in_array($type, $safe) || in_array('all', $safe);
+    }
+
+    protected function needEscaping(Twig_Environment $env)
+    {
+        if (count($this->statusStack)) {
+            return $this->statusStack[count($this->statusStack) - 1];
+        }
+
+        if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) {
+            return 'html';
+        }
+
+        return false;
+    }
+
+    protected function getEscaperFilter($type, Twig_NodeInterface $node)
+    {
+        $line = $node->getLine();
+        $name = new Twig_Node_Expression_Constant('escape', $line);
+        $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line)));
+        return new Twig_Node_Expression_Filter($node, $name, $args, $line);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 0;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Optimizer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Optimizer.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Optimizer.php	(revision 345)
@@ -0,0 +1,171 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_NodeVisitor_Optimizer tries to optimizes the AST.
+ *
+ * This visitor is always the last registered one.
+ *
+ * You can configure which optimizations you want to activate via the
+ * optimizer mode.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
+{
+    const OPTIMIZE_ALL         = -1;
+    const OPTIMIZE_NONE        = 0;
+    const OPTIMIZE_FOR         = 2;
+    const OPTIMIZE_RAW_FILTER  = 4;
+
+    protected $loops = array();
+    protected $optimizers;
+
+    /**
+     * Constructor.
+     *
+     * @param integer $optimizers The optimizer mode
+     */
+    public function __construct($optimizers = -1)
+    {
+        if (!is_int($optimizers) || $optimizers > 2) {
+            throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
+        }
+
+        $this->optimizers = $optimizers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
+            $this->enterOptimizeFor($node, $env);
+        }
+
+        return $node;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
+            $this->leaveOptimizeFor($node, $env);
+        }
+
+        if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) {
+            $node = $this->optimizeRawFilter($node, $env);
+        }
+
+        return $node;
+    }
+
+    /**
+     * Removes "raw" filters.
+     *
+     * @param Twig_NodeInterface $node A Node
+     * @param Twig_Environment   $env  The current Twig environment
+     */
+    protected function optimizeRawFilter($node, $env)
+    {
+        if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
+            return $node->getNode('node');
+        }
+
+        return $node;
+    }
+
+    /**
+     * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
+     *
+     * @param Twig_NodeInterface $node A Node
+     * @param Twig_Environment   $env  The current Twig environment
+     */
+    protected function enterOptimizeFor($node, $env)
+    {
+        if ($node instanceof Twig_Node_For) {
+            // disable the loop variable by default
+            $node->setAttribute('with_loop', false);
+            array_unshift($this->loops, $node);
+        } elseif (!$this->loops) {
+            // we are outside a loop
+            return;
+        }
+
+        // when do we need to add the loop variable back?
+
+        // the loop variable is referenced for the current loop
+        elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
+            $this->addLoopToCurrent();
+        }
+
+        // block reference
+        elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
+            $this->addLoopToCurrent();
+        }
+
+        // include without the only attribute
+        elseif ($node instanceof Twig_Node_Include && !$node->getAttribute('only')) {
+            $this->addLoopToAll();
+        }
+
+        // the loop variable is referenced via an attribute
+        elseif ($node instanceof Twig_Node_Expression_GetAttr
+            && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant
+                || 'parent' === $node->getNode('attribute')->getAttribute('value')
+               )
+            && (true === $this->loops[0]->getAttribute('with_loop')
+                || ($node->getNode('node') instanceof Twig_Node_Expression_Name
+                    && 'loop' === $node->getNode('node')->getAttribute('name')
+                   )
+               )
+        ) {
+            $this->addLoopToAll();
+        }
+    }
+
+    /**
+     * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
+     *
+     * @param Twig_NodeInterface $node A Node
+     * @param Twig_Environment   $env  The current Twig environment
+     */
+    protected function leaveOptimizeFor($node, $env)
+    {
+        if ($node instanceof Twig_Node_For) {
+            array_shift($this->loops);
+        }
+    }
+
+    protected function addLoopToCurrent()
+    {
+        $this->loops[0]->setAttribute('with_loop', true);
+    }
+
+    protected function addLoopToAll()
+    {
+        foreach ($this->loops as $loop) {
+            $loop->setAttribute('with_loop', true);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 255;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/SafeAnalysis.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/SafeAnalysis.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/SafeAnalysis.php	(revision 345)
@@ -0,0 +1,101 @@
+<?php
+
+class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
+{
+    protected $data = array();
+
+    public function getSafe(Twig_NodeInterface $node)
+    {
+        $hash = spl_object_hash($node);
+        if (isset($this->data[$hash])) {
+            foreach($this->data[$hash] as $bucket) {
+                if ($bucket['key'] === $node) {
+                    return $bucket['value'];
+                }
+            }
+        }
+        return null;
+    }
+
+    protected function setSafe(Twig_NodeInterface $node, array $safe)
+    {
+        $hash = spl_object_hash($node);
+        if (isset($this->data[$hash])) {
+            foreach($this->data[$hash] as &$bucket) {
+                if ($bucket['key'] === $node) {
+                    $bucket['value'] = $safe;
+                    return;
+                }
+            }
+        }
+        $this->data[$hash][] = array(
+            'key' => $node,
+            'value' => $safe,
+        );
+    }
+
+    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        return $node;
+    }
+
+    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_Expression_Constant) {
+            // constants are marked safe for all
+            $this->setSafe($node, array('all'));
+        } elseif ($node instanceof Twig_Node_Expression_Conditional) {
+            // intersect safeness of both operands
+            $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
+            $this->setSafe($node, $safe);
+        } elseif ($node instanceof Twig_Node_Expression_Filter) {
+            // filter expression is safe when the filter is safe
+            $name = $node->getNode('filter')->getAttribute('value');
+            $args = $node->getNode('arguments');
+            if (false !== $filter = $env->getFilter($name)) {
+                $this->setSafe($node, $filter->getSafe($args));
+            } else {
+                $this->setSafe($node, array());
+            }
+        } elseif ($node instanceof Twig_Node_Expression_Function) {
+            // function expression is safe when the function is safe
+            $name = $node->getNode('name')->getAttribute('name');
+            $args = $node->getNode('arguments');
+            $function = $env->getFunction($name);
+            if (false !== $function) {
+                $this->setSafe($node, $function->getSafe($args));
+            } else {
+                $this->setSafe($node, array());
+            }
+        } else {
+            $this->setSafe($node, array());
+        }
+
+        return $node;
+    }
+
+    protected function intersectSafe(array $a = null, array $b = null)
+    {
+        if (null === $a || null === $b) {
+            return array();
+        }
+
+        if (in_array('all', $a)) {
+            return $b;
+        }
+
+        if (in_array('all', $b)) {
+            return $a;
+        }
+
+        return array_intersect($a, $b);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 0;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Sandbox.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Sandbox.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Sandbox.php	(revision 345)
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_NodeVisitor_Sandbox implements sandboxing.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
+{
+    protected $inAModule = false;
+    protected $tags;
+    protected $filters;
+    protected $functions;
+
+    /**
+     * Called before child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_Module) {
+            $this->inAModule = true;
+            $this->tags = array();
+            $this->filters = array();
+            $this->functions = array();
+
+            return $node;
+        } elseif ($this->inAModule) {
+            // look for tags
+            if ($node->getNodeTag()) {
+                $this->tags[] = $node->getNodeTag();
+            }
+
+            // look for filters
+            if ($node instanceof Twig_Node_Expression_Filter) {
+                $this->filters[] = $node->getNode('filter')->getAttribute('value');
+            }
+
+            // look for functions
+            if ($node instanceof Twig_Node_Expression_Function) {
+                $this->functions[] = $node->getNode('name')->getAttribute('name');
+            }
+
+            // wrap print to check __toString() calls
+            if ($node instanceof Twig_Node_Print) {
+                return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag());
+            }
+        }
+
+        return $node;
+    }
+
+    /**
+     * Called after child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_Module) {
+            $this->inAModule = false;
+
+            return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions));
+        }
+
+        return $node;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 0;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitorInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitorInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitorInterface.php	(revision 345)
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_NodeVisitorInterface is the interface the all node visitor classes must implement.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_NodeVisitorInterface
+{
+    /**
+     * Called before child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    function enterNode(Twig_NodeInterface $node, Twig_Environment $env);
+
+    /**
+     * Called after child nodes are visited.
+     *
+     * @param Twig_NodeInterface $node The node to visit
+     * @param Twig_Environment   $env  The Twig environment instance
+     *
+     * @param Twig_NodeInterface The modified node
+     */
+    function leaveNode(Twig_NodeInterface $node, Twig_Environment $env);
+
+    /**
+     * Returns the priority for this visitor.
+     *
+     * Priority should be between -10 and 10 (0 is the default).
+     *
+     * @return integer The priority level
+     */
+    function getPriority();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Parser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Parser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Parser.php	(revision 345)
@@ -0,0 +1,302 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default parser implementation.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Parser implements Twig_ParserInterface
+{
+    protected $stream;
+    protected $parent;
+    protected $handlers;
+    protected $visitors;
+    protected $expressionParser;
+    protected $blocks;
+    protected $blockStack;
+    protected $macros;
+    protected $env;
+    protected $reservedMacroNames;
+    protected $importedFunctions;
+    protected $tmpVarCount;
+
+    /**
+     * Constructor.
+     *
+     * @param Twig_Environment $env A Twig_Environment instance
+     */
+    public function __construct(Twig_Environment $env)
+    {
+        $this->env = $env;
+    }
+
+    public function getVarName()
+    {
+        return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount);
+    }
+
+    /**
+     * Converts a token stream to a node tree.
+     *
+     * @param  Twig_TokenStream $stream A token stream instance
+     *
+     * @return Twig_Node_Module A node tree
+     */
+    public function parse(Twig_TokenStream $stream)
+    {
+        $this->tmpVarCount = 0;
+
+        // tag handlers
+        $this->handlers = $this->env->getTokenParsers();
+        $this->handlers->setParser($this);
+
+        // node visitors
+        $this->visitors = $this->env->getNodeVisitors();
+
+        if (null === $this->expressionParser) {
+            $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
+        }
+
+        $this->stream = $stream;
+        $this->parent = null;
+        $this->blocks = array();
+        $this->macros = array();
+        $this->blockStack = array();
+        $this->importedFunctions = array(array());
+
+        try {
+            $body = $this->subparse(null);
+
+            if (null !== $this->parent) {
+                $this->checkBodyNodes($body);
+            }
+        } catch (Twig_Error_Syntax $e) {
+            if (null === $e->getTemplateFile()) {
+                $e->setTemplateFile($this->stream->getFilename());
+            }
+
+            throw $e;
+        }
+
+        $node = new Twig_Node_Module($body, $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), $this->stream->getFilename());
+
+        $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
+
+        return $traverser->traverse($node);
+    }
+
+    public function subparse($test, $dropNeedle = false)
+    {
+        $lineno = $this->getCurrentToken()->getLine();
+        $rv = array();
+        while (!$this->stream->isEOF()) {
+            switch ($this->getCurrentToken()->getType()) {
+                case Twig_Token::TEXT_TYPE:
+                    $token = $this->stream->next();
+                    $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
+                    break;
+
+                case Twig_Token::VAR_START_TYPE:
+                    $token = $this->stream->next();
+                    $expr = $this->expressionParser->parseExpression();
+                    $this->stream->expect(Twig_Token::VAR_END_TYPE);
+                    $rv[] = new Twig_Node_Print($expr, $token->getLine());
+                    break;
+
+                case Twig_Token::BLOCK_START_TYPE:
+                    $this->stream->next();
+                    $token = $this->getCurrentToken();
+
+                    if ($token->getType() !== Twig_Token::NAME_TYPE) {
+                        throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine());
+                    }
+
+                    if (null !== $test && call_user_func($test, $token)) {
+                        if ($dropNeedle) {
+                            $this->stream->next();
+                        }
+
+                        if (1 === count($rv)) {
+                            return $rv[0];
+                        }
+
+                        return new Twig_Node($rv, array(), $lineno);
+                    }
+
+                    $subparser = $this->handlers->getTokenParser($token->getValue());
+                    if (null === $subparser) {
+                        throw new Twig_Error_Syntax(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine());
+                    }
+
+                    $this->stream->next();
+
+                    $node = $subparser->parse($token);
+                    if (null !== $node) {
+                        $rv[] = $node;
+                    }
+                    break;
+
+                default:
+                    throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.');
+            }
+        }
+
+        if (1 === count($rv)) {
+            return $rv[0];
+        }
+
+        return new Twig_Node($rv, array(), $lineno);
+    }
+
+    public function addHandler($name, $class)
+    {
+        $this->handlers[$name] = $class;
+    }
+
+    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
+    {
+        $this->visitors[] = $visitor;
+    }
+
+    public function getBlockStack()
+    {
+        return $this->blockStack;
+    }
+
+    public function peekBlockStack()
+    {
+        return $this->blockStack[count($this->blockStack) - 1];
+    }
+
+    public function popBlockStack()
+    {
+        array_pop($this->blockStack);
+    }
+
+    public function pushBlockStack($name)
+    {
+        $this->blockStack[] = $name;
+    }
+
+    public function hasBlock($name)
+    {
+        return isset($this->blocks[$name]);
+    }
+
+    public function setBlock($name, $value)
+    {
+        $this->blocks[$name] = $value;
+    }
+
+    public function hasMacro($name)
+    {
+        return isset($this->macros[$name]);
+    }
+
+    public function setMacro($name, Twig_Node_Macro $node)
+    {
+        if (null === $this->reservedMacroNames) {
+            $this->reservedMacroNames = array();
+            $r = new ReflectionClass($this->env->getBaseTemplateClass());
+            foreach ($r->getMethods() as $method) {
+                $this->reservedMacroNames[] = $method->getName();
+            }
+        }
+
+        if (in_array($name, $this->reservedMacroNames)) {
+            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine());
+        }
+
+        $this->macros[$name] = $node;
+    }
+
+    public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
+    {
+        $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
+    }
+
+    public function getImportedFunction($alias)
+    {
+        foreach ($this->importedFunctions as $functions) {
+            if (isset($functions[$alias])) {
+                return $functions[$alias];
+            }
+        }
+    }
+
+    public function pushLocalScope()
+    {
+        array_unshift($this->importedFunctions, array());
+    }
+
+    public function popLocalScope()
+    {
+        array_shift($this->importedFunctions);
+    }
+
+    /**
+     * Gets the expression parser.
+     *
+     * @return Twig_ExpressionParser The expression parser
+     */
+    public function getExpressionParser()
+    {
+        return $this->expressionParser;
+    }
+
+    public function getParent()
+    {
+        return $this->parent;
+    }
+
+    public function setParent($parent)
+    {
+        $this->parent = $parent;
+    }
+
+    /**
+     * Gets the token stream.
+     *
+     * @return Twig_TokenStream The token stream
+     */
+    public function getStream()
+    {
+        return $this->stream;
+    }
+
+    /**
+     * Gets the current token.
+     *
+     * @return Twig_Token The current token
+     */
+    public function getCurrentToken()
+    {
+        return $this->stream->getCurrent();
+    }
+
+    protected function checkBodyNodes($body)
+    {
+        // check that the body does not contain non-empty output nodes
+        foreach ($body as $node)
+        {
+            if (
+                ($node instanceof Twig_Node_Text && !ctype_space($node->getAttribute('data')))
+                ||
+                (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
+            ) {
+                throw new Twig_Error_Syntax(sprintf('A template that extends another one cannot have a body (%s).', $node), $node->getLine());
+            }
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/ParserInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/ParserInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/ParserInterface.php	(revision 345)
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by parser classes.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_ParserInterface
+{
+    /**
+     * Converts a token stream to a node tree.
+     *
+     * @param  Twig_TokenStream $stream A token stream instance
+     *
+     * @return Twig_Node_Module A node tree
+     */
+    function parse(Twig_TokenStream $code);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityError.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityError.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityError.php	(revision 345)
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when a security error occurs at runtime.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Sandbox_SecurityError extends Twig_Error
+{
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicy.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicy.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicy.php	(revision 345)
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a security policy which need to be enforced when sandbox mode is enabled.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface
+{
+    protected $allowedTags;
+    protected $allowedFilters;
+    protected $allowedMethods;
+    protected $allowedProperties;
+    protected $allowedFunctions;
+
+    public function __construct(array $allowedTags = array(), array $allowedFilters = array(), array $allowedMethods = array(), array $allowedProperties = array(), array $allowedFunctions = array())
+    {
+        $this->allowedTags = $allowedTags;
+        $this->allowedFilters = $allowedFilters;
+        $this->allowedMethods = $allowedMethods;
+        $this->allowedProperties = $allowedProperties;
+        $this->allowedFunctions = $allowedFunctions;
+    }
+
+    public function setAllowedTags(array $tags)
+    {
+        $this->allowedTags = $tags;
+    }
+
+    public function setAllowedFilters(array $filters)
+    {
+        $this->allowedFilters = $filters;
+    }
+
+    public function setAllowedMethods(array $methods)
+    {
+        $this->allowedMethods = $methods;
+    }
+
+    public function setAllowedProperties(array $properties)
+    {
+        $this->allowedProperties = $properties;
+    }
+
+    public function setAllowedFunctions(array $functions)
+    {
+        $this->allowedFunctions = $functions;
+    }
+
+    public function checkSecurity($tags, $filters, $functions)
+    {
+        foreach ($tags as $tag) {
+            if (!in_array($tag, $this->allowedTags)) {
+                throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag));
+            }
+        }
+
+        foreach ($filters as $filter) {
+            if (!in_array($filter, $this->allowedFilters)) {
+                throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter));
+            }
+        }
+
+        foreach ($functions as $function) {
+            if (!in_array($function, $this->allowedFunctions)) {
+                throw new Twig_Sandbox_SecurityError(sprintf('Function "%s" is not allowed.', $function));
+            }
+        }
+    }
+
+    public function checkMethodAllowed($obj, $method)
+    {
+        if ($obj instanceof Twig_TemplateInterface || $obj instanceof Twig_Markup) {
+            return true;
+        }
+
+        $allowed = false;
+        foreach ($this->allowedMethods as $class => $methods) {
+            if ($obj instanceof $class) {
+                $allowed = in_array($method, is_array($methods) ? $methods : array($methods));
+
+                break;
+            }
+        }
+
+        if (!$allowed) {
+            throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj)));
+        }
+    }
+
+    public function checkPropertyAllowed($obj, $property)
+    {
+        $allowed = false;
+        foreach ($this->allowedProperties as $class => $properties) {
+            if ($obj instanceof $class) {
+                $allowed = in_array($property, is_array($properties) ? $properties : array($properties));
+
+                break;
+            }
+        }
+
+        if (!$allowed) {
+            throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj)));
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicyInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicyInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Sandbox/SecurityPolicyInterface.php	(revision 345)
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interfaces that all security policy classes must implements.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_Sandbox_SecurityPolicyInterface
+{
+    function checkSecurity($tags, $filters, $functions);
+
+    function checkMethodAllowed($obj, $method);
+
+    function checkPropertyAllowed($obj, $method);
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Template.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Template.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Template.php	(revision 345)
@@ -0,0 +1,323 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default base class for compiled templates.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Twig_Template implements Twig_TemplateInterface
+{
+    static protected $cache = array();
+
+    protected $env;
+    protected $blocks;
+
+    /**
+     * Constructor.
+     *
+     * @param Twig_Environment $env A Twig_Environment instance
+     */
+    public function __construct(Twig_Environment $env)
+    {
+        $this->env = $env;
+        $this->blocks = array();
+    }
+
+    /**
+     * Returns the template name.
+     *
+     * @return string The template name
+     */
+    public function getTemplateName()
+    {
+        return null;
+    }
+
+    /**
+     * Returns the Twig environment.
+     *
+     * @return Twig_Environment The Twig environment
+     */
+    public function getEnvironment()
+    {
+        return $this->env;
+    }
+
+    /**
+     * Returns the parent template.
+     *
+     * @return Twig_TemplateInterface|false The parent template or false if there is no parent
+     */
+    public function getParent(array $context)
+    {
+        return false;
+    }
+
+    /**
+     * Displays a parent block.
+     *
+     * @param string $name    The block name to display from the parent
+     * @param array  $context The context
+     * @param array  $blocks  The current set of blocks
+     */
+    public function displayParentBlock($name, array $context, array $blocks = array())
+    {
+        if (false !== $parent = $this->getParent($context)) {
+            $parent->displayBlock($name, $context, $blocks);
+        } else {
+            throw new Twig_Error_Runtime('This template has no parent', -1, $this->getTemplateName());
+        }
+    }
+
+    /**
+     * Displays a block.
+     *
+     * @param string $name    The block name to display
+     * @param array  $context The context
+     * @param array  $blocks  The current set of blocks
+     */
+    public function displayBlock($name, array $context, array $blocks = array())
+    {
+        if (isset($blocks[$name])) {
+            $b = $blocks;
+            unset($b[$name]);
+            call_user_func($blocks[$name], $context, $b);
+        } elseif (isset($this->blocks[$name])) {
+            call_user_func($this->blocks[$name], $context, $blocks);
+        } elseif (false !== $parent = $this->getParent($context)) {
+            $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
+        }
+    }
+
+    /**
+     * Renders a parent block.
+     *
+     * @param string $name    The block name to render from the parent
+     * @param array  $context The context
+     * @param array  $blocks  The current set of blocks
+     *
+     * @return string The rendered block
+     */
+    public function renderParentBlock($name, array $context, array $blocks = array())
+    {
+        ob_start();
+        $this->displayParentBlock($name, $context, $blocks);
+
+        return new Twig_Markup(ob_get_clean());
+    }
+
+    /**
+     * Renders a block.
+     *
+     * @param string $name    The block name to render
+     * @param array  $context The context
+     * @param array  $blocks  The current set of blocks
+     *
+     * @return string The rendered block
+     */
+    public function renderBlock($name, array $context, array $blocks = array())
+    {
+        ob_start();
+        $this->displayBlock($name, $context, $blocks);
+
+        return new Twig_Markup(ob_get_clean());
+    }
+
+    /**
+     * Returns whether a block exists or not.
+     *
+     * @param string $name The block name
+     *
+     * @return Boolean true if the block exists, false otherwise
+     */
+    public function hasBlock($name)
+    {
+        return isset($this->blocks[$name]);
+    }
+
+    /**
+     * Returns all block names.
+     *
+     * @return array An array of block names
+     */
+    public function getBlockNames()
+    {
+        return array_keys($this->blocks);
+    }
+
+    /**
+     * Displays the template with the given context.
+     *
+     * @param array $context An array of parameters to pass to the template
+     * @param array $blocks  An array of blocks to pass to the template
+     */
+    public function display(array $context, array $blocks = array())
+    {
+        try {
+            $this->doDisplay($context, $blocks);
+        } catch (Twig_Error $e) {
+            throw $e;
+        } catch (Exception $e) {
+            throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e);
+        }
+    }
+
+    /**
+     * Renders the template with the given context and returns it as string.
+     *
+     * @param array $context An array of parameters to pass to the template
+     *
+     * @return string The rendered template
+     */
+    public function render(array $context)
+    {
+        ob_start();
+        try {
+            $this->display($context);
+        } catch (Exception $e) {
+            // the count variable avoids an infinite loop on
+            // some Windows configurations where ob_get_level()
+            // never reaches 0
+            $count = 100;
+            while (ob_get_level() && --$count) {
+                ob_end_clean();
+            }
+
+            throw $e;
+        }
+
+        return ob_get_clean();
+    }
+
+    /**
+     * Auto-generated method to display the template with the given context.
+     *
+     * @param array $context An array of parameters to pass to the template
+     * @param array $blocks  An array of blocks to pass to the template
+     */
+    abstract protected function doDisplay(array $context, array $blocks = array());
+
+    /**
+     * Returns a variable from the context.
+     *
+     * @param array   $context The context
+     * @param string  $item    The variable to return from the context
+     *
+     * @param mixed The variable value in the context
+     *
+     * @throws Twig_Error_Runtime if the variable does not exist
+     */
+    protected function getContext($context, $item)
+    {
+        if (!array_key_exists($item, $context)) {
+            throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item));
+        }
+
+        return $context[$item];
+    }
+
+    /**
+     * Returns the attribute value for a given array/object.
+     *
+     * @param mixed   $object        The object or array from where to get the item
+     * @param mixed   $item          The item to get from the array or object
+     * @param array   $arguments     An array of arguments to pass if the item is an object method
+     * @param integer $type          The type of attribute (@see Twig_TemplateInterface)
+     * @param Boolean $noStrictCheck Whether to throw an exception if the item does not exist ot not
+     */
+    protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $noStrictCheck = false)
+    {
+        // array
+        if (Twig_TemplateInterface::METHOD_CALL !== $type) {
+            if ((is_array($object) || is_object($object) && $object instanceof ArrayAccess) && isset($object[$item])) {
+                return $object[$item];
+            }
+
+            if (Twig_TemplateInterface::ARRAY_CALL === $type) {
+                if (!$this->env->isStrictVariables() || $noStrictCheck) {
+                    return null;
+                }
+
+                if (is_object($object)) {
+                    throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $item, get_class($object)));
+                // array
+                } else {
+                    throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object))));
+                }
+            }
+        }
+
+        if (!is_object($object)) {
+            if (!$this->env->isStrictVariables() || $noStrictCheck) {
+                return null;
+            }
+            throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, $object));
+        }
+
+        // get some information about the object
+        $class = get_class($object);
+        if (!isset(self::$cache[$class])) {
+            $r = new ReflectionClass($class);
+            self::$cache[$class] = array('methods' => array(), 'properties' => array());
+            foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
+                self::$cache[$class]['methods'][strtolower($method->getName())] = true;
+            }
+
+            foreach ($r->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
+                self::$cache[$class]['properties'][$property->getName()] = true;
+            }
+        }
+
+        // object property
+        if (Twig_TemplateInterface::METHOD_CALL !== $type) {
+            if (isset(self::$cache[$class]['properties'][$item]) || isset($object->$item)) {
+                if ($this->env->hasExtension('sandbox')) {
+                    $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
+                }
+
+                return $object->$item;
+            }
+        }
+
+        // object method
+        $lcItem = strtolower($item);
+        if (isset(self::$cache[$class]['methods'][$lcItem])) {
+            $method = $item;
+        } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) {
+            $method = 'get'.$item;
+        } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) {
+            $method = 'is'.$item;
+        } elseif (isset(self::$cache[$class]['methods']['__call'])) {
+            $method = $item;
+        } else {
+            if (!$this->env->isStrictVariables() || $noStrictCheck) {
+                return null;
+            }
+
+            throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)));
+        }
+
+        if ($this->env->hasExtension('sandbox')) {
+            $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
+        }
+
+        $ret = call_user_func_array(array($object, $method), $arguments);
+
+        if ($object instanceof Twig_TemplateInterface) {
+            return new Twig_Markup($ret);
+        }
+
+        return $ret;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TemplateInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TemplateInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TemplateInterface.php	(revision 345)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by all compiled templates.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_TemplateInterface
+{
+    const ANY_CALL    = 'any';
+    const ARRAY_CALL  = 'array';
+    const METHOD_CALL = 'method';
+
+    /**
+     * Renders the template with the given context and returns it as string.
+     *
+     * @param array $context An array of parameters to pass to the template
+     *
+     * @return string The rendered template
+     */
+    function render(array $context);
+
+    /**
+     * Displays the template with the given context.
+     *
+     * @param array $context An array of parameters to pass to the template
+     * @param array $blocks  An array of blocks to pass to the template
+     */
+    function display(array $context, array $blocks = array());
+
+    /**
+     * Returns the bound environment for this template.
+     *
+     * @return Twig_Environment The current environment
+     */
+    function getEnvironment();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Function.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Function.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Function.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a function template test.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Test_Function implements Twig_TestInterface
+{
+    protected $function;
+
+    public function __construct($function)
+    {
+        $this->function = $function;
+    }
+
+    public function compile()
+    {
+        return $this->function;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Method.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Method.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Test/Method.php	(revision 345)
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a method template test.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Test_Method implements Twig_TestInterface
+{
+    protected $extension, $method;
+
+    public function __construct(Twig_ExtensionInterface $extension, $method)
+    {
+        $this->extension = $extension;
+        $this->method = $method;
+    }
+
+    public function compile()
+    {
+        return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TestInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TestInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TestInterface.php	(revision 345)
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a template test.
+ *
+ * @package    twig
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_TestInterface
+{
+    /**
+     * Compiles a test.
+     *
+     * @return string The PHP code for the test
+     */
+    function compile();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/Token.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/Token.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/Token.php	(revision 345)
@@ -0,0 +1,206 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a Token.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Token
+{
+    protected $value;
+    protected $type;
+    protected $lineno;
+
+    const EOF_TYPE         = -1;
+    const TEXT_TYPE        = 0;
+    const BLOCK_START_TYPE = 1;
+    const VAR_START_TYPE   = 2;
+    const BLOCK_END_TYPE   = 3;
+    const VAR_END_TYPE     = 4;
+    const NAME_TYPE        = 5;
+    const NUMBER_TYPE      = 6;
+    const STRING_TYPE      = 7;
+    const OPERATOR_TYPE    = 8;
+    const PUNCTUATION_TYPE = 9;
+
+    /**
+     * Constructor.
+     *
+     * @param integer $type   The type of the token
+     * @param string  $value  The token value
+     * @param integer $lineno The line position in the source
+     */
+    public function __construct($type, $value, $lineno)
+    {
+        $this->type   = $type;
+        $this->value  = $value;
+        $this->lineno = $lineno;
+    }
+
+    /**
+     * Returns a string representation of the token.
+     *
+     * @return string A string representation of the token
+     */
+    public function __toString()
+    {
+        return sprintf('%s(%s)', self::typeToString($this->type, true, $this->lineno), $this->value);
+    }
+
+    /**
+     * Tests the current token for a type and/or a value.
+     *
+     * Parameters may be:
+     * * just type
+     * * type and value (or array of possible values)
+     * * just value (or array of possible values) (NAME_TYPE is used as type)
+     *
+     * @param array|integer     $type   The type to test
+     * @param array|string|null $values The token value
+     *
+     * @return Boolean
+     */
+    public function test($type, $values = null)
+    {
+        if (null === $values && !is_int($type)) {
+            $values = $type;
+            $type = self::NAME_TYPE;
+        }
+
+        return ($this->type === $type) && (
+            null === $values ||
+            (is_array($values) && in_array($this->value, $values)) ||
+            $this->value == $values
+        );
+    }
+
+    /**
+     * Gets the line.
+     *
+     * @return integer The source line
+     */
+    public function getLine()
+    {
+        return $this->lineno;
+    }
+
+    /**
+     * Gets the token type.
+     *
+     * @return integer The token type
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Gets the token value.
+     *
+     * @return string The token value
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * Returns the constant representation (internal) of a given type.
+     *
+     * @param integer $type  The type as an integer
+     * @param Boolean $short Whether to return a short representation or not
+     *
+     * @return string The string representation
+     */
+    static public function typeToString($type, $short = false, $line = -1)
+    {
+        switch ($type) {
+            case self::EOF_TYPE:
+                $name = 'EOF_TYPE';
+                break;
+            case self::TEXT_TYPE:
+                $name = 'TEXT_TYPE';
+                break;
+            case self::BLOCK_START_TYPE:
+                $name = 'BLOCK_START_TYPE';
+                break;
+            case self::VAR_START_TYPE:
+                $name = 'VAR_START_TYPE';
+                break;
+            case self::BLOCK_END_TYPE:
+                $name = 'BLOCK_END_TYPE';
+                break;
+            case self::VAR_END_TYPE:
+                $name = 'VAR_END_TYPE';
+                break;
+            case self::NAME_TYPE:
+                $name = 'NAME_TYPE';
+                break;
+            case self::NUMBER_TYPE:
+                $name = 'NUMBER_TYPE';
+                break;
+            case self::STRING_TYPE:
+                $name = 'STRING_TYPE';
+                break;
+            case self::OPERATOR_TYPE:
+                $name = 'OPERATOR_TYPE';
+                break;
+            case self::PUNCTUATION_TYPE:
+                $name = 'PUNCTUATION_TYPE';
+                break;
+            default:
+                throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line);
+        }
+
+        return $short ? $name : 'Twig_Token::'.$name;
+    }
+
+    /**
+     * Returns the english representation of a given type.
+     *
+     * @param integer $type  The type as an integer
+     * @param Boolean $short Whether to return a short representation or not
+     *
+     * @return string The string representation
+     */
+    static public function typeToEnglish($type, $line = -1)
+    {
+        switch ($type) {
+            case self::EOF_TYPE:
+                return 'end of template';
+            case self::TEXT_TYPE:
+                return 'text';
+            case self::BLOCK_START_TYPE:
+                return 'begin of statement block';
+            case self::VAR_START_TYPE:
+                return 'begin of print statement';
+            case self::BLOCK_END_TYPE:
+                return 'end of statement block';
+            case self::VAR_END_TYPE:
+                return 'end of print statement';
+            case self::NAME_TYPE:
+                return 'name';
+            case self::NUMBER_TYPE:
+                return 'number';
+            case self::STRING_TYPE:
+                return 'string';
+            case self::OPERATOR_TYPE:
+                return 'operator';
+            case self::PUNCTUATION_TYPE:
+                return 'punctuation';
+            default:
+                throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser.php	(revision 345)
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base class for all token parsers.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Twig_TokenParser implements Twig_TokenParserInterface
+{
+    protected $parser;
+
+    /**
+     * Sets the parser associated with this token parser
+     *
+     * @param $parser A Twig_Parser instance
+     */
+    public function setParser(Twig_Parser $parser)
+    {
+        $this->parser = $parser;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/AutoEscape.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/AutoEscape.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/AutoEscape.php	(revision 345)
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_AutoEscape extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $value = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+        if (!in_array($value, array('true', 'false'))) {
+            throw new Twig_Error_Syntax("Autoescape value must be 'true' or 'false'", $lineno);
+        }
+        $value = 'true' === $value ? 'html' : false;
+
+        if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) {
+            if (false === $value) {
+                throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $lineno);
+            }
+
+            $value = $this->parser->getStream()->next()->getValue();
+        }
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag());
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endautoescape');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'autoescape';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Block.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Block.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Block.php	(revision 345)
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Block extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $stream = $this->parser->getStream();
+        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+        if ($this->parser->hasBlock($name)) {
+            throw new Twig_Error_Syntax("The block '$name' has already been defined", $lineno);
+        }
+        $this->parser->pushLocalScope();
+        $this->parser->pushBlockStack($name);
+
+        if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
+            $stream->next();
+
+            $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+            if ($stream->test(Twig_Token::NAME_TYPE)) {
+                $value = $stream->next()->getValue();
+
+                if ($value != $name) {
+                    throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
+                }
+            }
+        } else {
+            $body = new Twig_Node(array(
+                new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
+            ));
+        }
+        $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+        $block = new Twig_Node_Block($name, $body, $lineno);
+        $this->parser->setBlock($name, $block);
+        $this->parser->popBlockStack();
+        $this->parser->popLocalScope();
+
+        return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endblock');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'block';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Extends.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Extends.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Extends.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Extends extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        if (null !== $this->parser->getParent()) {
+            throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine());
+        }
+        $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return null;
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'extends';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Filter.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Filter.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Filter.php	(revision 345)
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Filter extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $name = $this->parser->getVarName();
+        $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), true, $token->getLine(), $this->getTag());
+
+        $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        $block = new Twig_Node_Block($name, $body, $token->getLine());
+        $this->parser->setBlock($name, $block);
+
+        return new Twig_Node_Print($filter, $token->getLine(), $this->getTag());
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endfilter');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'filter';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/For.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/For.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/For.php	(revision 345)
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_For extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
+        $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in');
+        $seq = $this->parser->getExpressionParser()->parseExpression();
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $body = $this->parser->subparse(array($this, 'decideForFork'));
+        if ($this->parser->getStream()->next()->getValue() == 'else') {
+            $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+            $else = $this->parser->subparse(array($this, 'decideForEnd'), true);
+        } else {
+            $else = null;
+        }
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        if (count($targets) > 1) {
+            $keyTarget = $targets->getNode(0);
+            $valueTarget = $targets->getNode(1);
+        } else {
+            $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
+            $valueTarget = $targets->getNode(0);
+        }
+
+        return new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $lineno, $this->getTag());
+    }
+
+    public function decideForFork(Twig_Token $token)
+    {
+        return $token->test(array('else', 'endfor'));
+    }
+
+    public function decideForEnd(Twig_Token $token)
+    {
+        return $token->test('endfor');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'for';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/From.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/From.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/From.php	(revision 345)
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_From extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $macro = $this->parser->getExpressionParser()->parseExpression();
+        $stream = $this->parser->getStream();
+        $stream->expect('import');
+
+        $targets = array();
+        do {
+            $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+
+            $alias = $name;
+            if ($stream->test('as')) {
+                $stream->next();
+
+                $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+            }
+
+            $targets[$name] = $alias;
+
+            if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+                break;
+            }
+
+            $stream->next();
+        } while (true);
+
+        $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+        $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
+
+        foreach($targets as $name => $alias) {
+            $this->parser->addImportedFunction($alias, $name, $node->getNode('var'));
+        }
+
+        return $node;
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'from';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/If.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/If.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/If.php	(revision 345)
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_If extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $expr = $this->parser->getExpressionParser()->parseExpression();
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $body = $this->parser->subparse(array($this, 'decideIfFork'));
+        $tests = array($expr, $body);
+        $else = null;
+
+        $end = false;
+        while (!$end) {
+            switch ($this->parser->getStream()->next()->getValue()) {
+                case 'else':
+                    $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+                    $else = $this->parser->subparse(array($this, 'decideIfEnd'));
+                    break;
+
+                case 'elseif':
+                    $expr = $this->parser->getExpressionParser()->parseExpression();
+                    $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+                    $body = $this->parser->subparse(array($this, 'decideIfFork'));
+                    $tests[] = $expr;
+                    $tests[] = $body;
+                    break;
+
+                case 'endif':
+                    $end = true;
+                    break;
+
+                default:
+                    throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), -1);
+            }
+        }
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag());
+    }
+
+    public function decideIfFork(Twig_Token $token)
+    {
+        return $token->test(array('elseif', 'else', 'endif'));
+    }
+
+    public function decideIfEnd(Twig_Token $token)
+    {
+        return $token->test(array('endif'));
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'if';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Import.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Import.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Import.php	(revision 345)
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Import extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $macro = $this->parser->getExpressionParser()->parseExpression();
+        $this->parser->getStream()->expect('as');
+        $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine());
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'import';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Include.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Include.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Include.php	(revision 345)
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Include extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $expr = $this->parser->getExpressionParser()->parseExpression();
+
+        $variables = null;
+        if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'with')) {
+            $this->parser->getStream()->next();
+
+            $variables = $this->parser->getExpressionParser()->parseExpression();
+        }
+
+        $only = false;
+        if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'only')) {
+            $this->parser->getStream()->next();
+
+            $only = true;
+        }
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_Include($expr, $variables, $only, $token->getLine(), $this->getTag());
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'include';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Macro.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Macro.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Macro.php	(revision 345)
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Macro extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+
+        $arguments = $this->parser->getExpressionParser()->parseArguments();
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $this->parser->pushLocalScope();
+        $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+        if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) {
+            $value = $this->parser->getStream()->next()->getValue();
+
+            if ($value != $name) {
+                throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $lineno);
+            }
+        }
+        $this->parser->popLocalScope();
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        $this->parser->setMacro($name, new Twig_Node_Macro($name, $body, $arguments, $lineno, $this->getTag()));
+
+        return null;
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endmacro');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'macro';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Sandbox.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Sandbox.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Sandbox.php	(revision 345)
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Sandbox extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag());
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endsandbox');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'sandbox';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Set.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Set.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Set.php	(revision 345)
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Set extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+        $stream = $this->parser->getStream();
+        $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
+
+        $capture = false;
+        if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) {
+            $stream->next();
+            $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
+
+            $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+            if (count($names) !== count($values)) {
+                throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignements.", $lineno);
+            }
+        } else {
+            $capture = true;
+
+            if (count($names) > 1) {
+                throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $lineno);
+            }
+
+            $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+            $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+            $stream->expect(Twig_Token::BLOCK_END_TYPE);
+        }
+
+        return new Twig_Node_Set($capture, $names, $values, $lineno, $this->getTag());
+    }
+
+    public function decideBlockEnd(Twig_Token $token)
+    {
+        return $token->test('endset');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'set';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Spaceless.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Spaceless.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParser/Spaceless.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_TokenParser_Spaceless extends Twig_TokenParser
+{
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    public function parse(Twig_Token $token)
+    {
+        $lineno = $token->getLine();
+
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $body = $this->parser->subparse(array($this, 'decideSpacelessEnd'), true);
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_Spaceless($body, $lineno, $this->getTag());
+    }
+
+    public function decideSpacelessEnd(Twig_Token $token)
+    {
+        return $token->test('endspaceless');
+    }
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    public function getTag()
+    {
+        return 'spaceless';
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBroker.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBroker.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBroker.php	(revision 345)
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default implementation of a token parser broker.
+ *
+ * @package twig
+ * @author  Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
+{
+    protected $parser;
+    protected $parsers = array();
+    protected $brokers = array();
+
+    /**
+     * Constructor.
+     *
+     * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances
+     * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances
+     */
+    public function __construct($parsers = array(), $brokers = array())
+    {
+        foreach($parsers as $parser) {
+            if (!$parser instanceof Twig_TokenParserInterface) {
+                throw new Twig_Error('$parsers must a an array of Twig_TokenParserInterface');
+            }
+            $this->parsers[$parser->getTag()] = $parser;
+        }
+        foreach($brokers as $broker) {
+            if (!$broker instanceof Twig_TokenParserBrokerInterface) {
+                throw new Twig_Error('$brokers must a an array of Twig_TokenParserBrokerInterface');
+            }
+            $this->brokers[] = $broker;
+        }
+	}
+
+    /**
+     * Adds a TokenParser.
+     *
+     * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
+     */
+    public function addTokenParser(Twig_TokenParserInterface $parser)
+    {
+        $this->parsers[$parser->getTag()] = $parser;
+    }
+
+    /**
+     * Adds a TokenParserBroker.
+     *
+     * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance
+     */
+    public function addTokenParserBroker(Twig_TokenParserBroker $broker)
+    {
+        $this->brokers[] = $broker;
+    }
+
+    /**
+     * Gets a suitable TokenParser for a tag.
+     *
+     * First looks in parsers, then in brokers.
+     *
+     * @param string $tag A tag name
+     *
+     * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found
+     */
+    public function getTokenParser($tag)
+    {
+        if (isset($this->parsers[$tag])) {
+            return $this->parsers[$tag];
+        }
+        $broker = end($this->brokers);
+        while (false !== $broker) {
+            $parser = $broker->getTokenParser($tag);
+            if (null !== $parser) {
+                return $parser;
+            }
+            $broker = prev($this->brokers);
+        }
+        return null;
+    }
+
+    public function getParser()
+    {
+        return $this->parser;
+    }
+
+    public function setParser(Twig_ParserInterface $parser)
+    {
+        $this->parser = $parser;
+        foreach ($this->parsers as $tokenParser) {
+            $tokenParser->setParser($parser);
+        }
+        foreach ($this->brokers as $broker) {
+            $broker->setParser($parser);
+        }
+    }
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBrokerInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBrokerInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserBrokerInterface.php	(revision 345)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by token parser brokers.
+ *
+ * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name.
+ *
+ * @package twig
+ * @author  Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+interface Twig_TokenParserBrokerInterface
+{
+    /**
+     * Gets a TokenParser suitable for a tag.
+     *
+     * @param  string $tag A tag name
+     *
+     * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found
+     */
+    function getTokenParser($tag);
+
+    /**
+     * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of.
+     *
+     * @param Twig_ParserInterface $parser A Twig_ParserInterface interface
+     */
+    function setParser(Twig_ParserInterface $parser);
+
+    /**
+     * Gets the Twig_ParserInterface.
+     *
+     * @return null|Twig_ParserInterface A Twig_ParserInterface instance of null
+     */
+    function getParser();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserInterface.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserInterface.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenParserInterface.php	(revision 345)
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by token parsers.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface Twig_TokenParserInterface
+{
+    /**
+     * Sets the parser associated with this token parser
+     *
+     * @param $parser A Twig_Parser instance
+     */
+    function setParser(Twig_Parser $parser);
+
+    /**
+     * Parses a token and returns a node.
+     *
+     * @param Twig_Token $token A Twig_Token instance
+     *
+     * @return Twig_NodeInterface A Twig_NodeInterface instance
+     */
+    function parse(Twig_Token $token);
+
+    /**
+     * Gets the tag name associated with this token parser.
+     *
+     * @param string The tag name
+     */
+    function getTag();
+}
Index: pro-violet-viettel/sourcecode/application/third_party/Twig/TokenStream.php
===================================================================
--- pro-violet-viettel/sourcecode/application/third_party/Twig/TokenStream.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/third_party/Twig/TokenStream.php	(revision 345)
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a token stream.
+ *
+ * @package twig
+ * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_TokenStream
+{
+    protected $tokens;
+    protected $current;
+    protected $filename;
+
+    /**
+     * Constructor.
+     *
+     * @param array  $tokens   An array of tokens
+     * @param string $filename The name of the filename which tokens are associated with
+     */
+    public function __construct(array $tokens, $filename = null)
+    {
+        $this->tokens     = $tokens;
+        $this->current    = 0;
+        $this->filename   = $filename;
+    }
+
+    /**
+     * Returns a string representation of the token stream.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return implode("\n", $this->tokens);
+    }
+
+    /**
+     * Sets the pointer to the next token and returns the old one.
+     *
+     * @return Twig_Token
+     */
+    public function next()
+    {
+        if (!isset($this->tokens[++$this->current])) {
+            throw new Twig_Error_Syntax('Unexpected end of template');
+        }
+
+        return $this->tokens[$this->current - 1];
+    }
+
+    /**
+     * Tests a token and returns it or throws a syntax error.
+     *
+     * @return Twig_Token
+     */
+    public function expect($type, $value = null, $message = null)
+    {
+        $token = $this->tokens[$this->current];
+        if (!$token->test($type, $value)) {
+            $line = $token->getLine();
+            throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)',
+                $message ? $message.'. ' : '',
+                Twig_Token::typeToEnglish($token->getType(), $line), $token->getValue(),
+                Twig_Token::typeToEnglish($type, $line), $value ? sprintf(' with value "%s"', $value) : ''),
+                $line
+            );
+        }
+        $this->next();
+
+        return $token;
+    }
+
+    /**
+     * Looks at the next token.
+     *
+     * @param integer $number
+     *
+     * @return Twig_Token
+     */
+    public function look($number = 1)
+    {
+        if (!isset($this->tokens[$this->current + $number])) {
+            throw new Twig_Error_Syntax('Unexpected end of template');
+        }
+
+        return $this->tokens[$this->current + $number];
+    }
+
+    /**
+     * Tests the current token
+     *
+     * @return bool
+     */
+    public function test($primary, $secondary = null)
+    {
+        return $this->tokens[$this->current]->test($primary, $secondary);
+    }
+
+    /**
+     * Checks if end of stream was reached
+     *
+     * @return bool
+     */
+    public function isEOF()
+    {
+        return $this->tokens[$this->current]->getType() === Twig_Token::EOF_TYPE;
+    }
+
+    /**
+     * Gets the current token
+     *
+     * @return Twig_Token
+     */
+    public function getCurrent()
+    {
+        return $this->tokens[$this->current];
+    }
+
+    /**
+     * Gets the filename associated with this stream
+     *
+     * @return string
+     */
+    public function getFilename()
+    {
+        return $this->filename;
+    }
+}
Index: pro-violet-viettel/sourcecode/application/views/index.php
===================================================================
--- pro-violet-viettel/sourcecode/application/views/index.php	(revision 345)
+++ pro-violet-viettel/sourcecode/application/views/index.php	(revision 345)
@@ -0,0 +1,1 @@
+123456
Index: pro-violet-viettel/sourcecode/application/views/layout/admin/footer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/views/layout/admin/footer.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/views/layout/admin/footer.php	(revision 345)
@@ -172,5 +172,17 @@
 				},
 			});
+                             
 		</script>
+                <?php
+                if (isset($adminjs))
+                {
+                foreach ($adminjs as $file)
+                {
+                ?>
+                <script type="text/javascript" src="<?php echo $base_url;?><?php echo $file?>"></script>
+                <?php
+                }
+                }
+                ?>
 	</body>
 </html>
Index: pro-violet-viettel/sourcecode/application/views/layout/footer.php
===================================================================
--- pro-violet-viettel/sourcecode/application/views/layout/footer.php	(revision 344)
+++ pro-violet-viettel/sourcecode/application/views/layout/footer.php	(revision 345)
@@ -60,4 +60,6 @@
         });
     }
+    
+
 </script>
 </body>
Index: pro-violet-viettel/sourcecode/system/libraries/Pagination.php
===================================================================
--- pro-violet-viettel/sourcecode/system/libraries/Pagination.php	(revision 344)
+++ pro-violet-viettel/sourcecode/system/libraries/Pagination.php	(revision 345)
@@ -35,4 +35,5 @@
 	var $num_links			=  2; // Number of "digit" links to show before/after the currently viewed page
 	var $cur_page			=  0; // The current page being viewed
+        var $current_page	        =  0;
 	var $use_page_numbers	= FALSE; // Use page number for segment instead of offset
 	var $first_link			= '&lsaquo; First';
@@ -59,4 +60,5 @@
 	var $query_string_segment = 'per_page';
 	var $display_pages		= TRUE;
+        var $ajax_class		= '';
 	var $anchor_class		= '';
 
@@ -100,4 +102,5 @@
 				{
 					$this->$key = $val;
+                                        
 				}
 			}
@@ -162,4 +165,11 @@
 				$this->cur_page = (int) $this->cur_page;
 			}
+                        
+                       
+                        if ($this->current_page)
+			{
+                		// Prep the current page - no funny business!
+				$this->cur_page = (int) $this->current_page;
+			}
 		}
 		
@@ -229,5 +239,5 @@
 		{
 			$first_url = ($this->first_url == '') ? $this->base_url : $this->first_url;
-			$output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
+			$output .= $this->first_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
 		}
 
@@ -246,10 +256,10 @@
 			if ($i == 0 && $this->first_url != '')
 			{
-				$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
+				$output .= $this->prev_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
 			}
 			else
 			{
 				$i = ($i == 0) ? '' : $this->prefix.$i.$this->suffix;
-				$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
+				$output .= $this->prev_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
 			}
 
@@ -283,5 +293,5 @@
 						if ($n == '' && $this->first_url != '')
 						{
-							$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
+							$output .= $this->num_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
 						}
 						else
@@ -289,5 +299,5 @@
 							$n = ($n == '') ? '' : $this->prefix.$n.$this->suffix;
 
-							$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
+							$output .= $this->num_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
 						}
 					}
@@ -296,5 +306,5 @@
 		}
 
-		// Render the "next" link
+			
 		if ($this->next_link !== FALSE AND $this->cur_page < $num_pages)
 		{
@@ -307,6 +317,6 @@
 				$i = ($this->cur_page * $this->per_page);
 			}
-
-			$output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
+                        
+                        $output .= $this->next_tag_open.'<a  class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
 		}
 
@@ -322,5 +332,5 @@
 				$i = (($num_pages * $this->per_page) - $this->per_page);
 			}
-			$output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->last_link.'</a>'.$this->last_tag_close;
+			$output .= $this->last_tag_open.'<a class ="'.$this->ajax_class.'"'.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->last_link.'</a>'.$this->last_tag_close;
 		}
 
@@ -331,5 +341,4 @@
 		// Add the wrapper HTML if exists
 		$output = $this->full_tag_open.$output.$this->full_tag_close;
-
 		return $output;
 	}
